/*
*         Copyright (c), NXP Semiconductors Bangalore / India
*
*                     (C)NXP Semiconductors
*       All rights are reserved. Reproduction in whole or in part is
*      prohibited without the written consent of the copyright owner.
*  NXP reserves the right to make changes without notice at any time.
* NXP makes no warranty, expressed, implied or statutory, including but
* not limited to any implied warranty of merchantability or fitness for any
*particular purpose, or that the use will not infringe any third party patent,
* copyright or trademark. NXP must not be liable for any loss or damage
*                          arising from its use.
*/

#include <ph_Status.h>
#include <ph_RefDefs.h>
#include <ph_TypeDefs.h>
#include <phhalHw.h>
#include <phpalMifare.h>
#include <string.h>

#ifdef NXPBUILD__PHAL_MFDFEVX_SAM_X

#include "../phalMfdfEVx_Int.h"
#include "phalMfdfEVx_Sam_X.h"
#include "phalMfdfEVx_Sam_X_Int.h"
#include <phhalHw_SamAV3_Cmd.h>

phStatus_t phalMfdfEVx_SamAV3_X_Init(phalMfdfEVx_SamAV3_X_DataParams_t * pDataParams, uint16_t wSizeOfDataParams, 
	phhalHw_SamAV3_DataParams_t * pHalSamDataParams, phTMIUtils_t * pTMIDataParams, uint8_t * pTmpBuffer,
	uint16_t wTmpBufSize)
{
    /* data param check */
    if (sizeof(phalMfdfEVx_SamAV3_X_DataParams_t) != wSizeOfDataParams)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_DATA_PARAMS, PH_COMP_AL_MFDFEVX);
    }
	
	/* Temporary Buffer size check. */
	if(wTmpBufSize < 256 )
    {
        return PH_ADD_COMPCODE(PH_ERR_PARAMETER_SIZE, PH_COMP_AL_MFDFEVX);
    }

    PH_ASSERT_NULL_DATA_PARAM (pDataParams, PH_COMP_AL_MFDFEVX);
    PH_ASSERT_NULL_PARAM (pHalSamDataParams, PH_COMP_AL_MFDFEVX);

    /* init private data */
	pDataParams->wId					= PH_COMP_AL_MFDFEVX | PHAL_MFDFEVX_SAMAV3_X_ID;
    pDataParams->pHalSamDataParams		= pHalSamDataParams;
    pDataParams->pTMIDataParams			= pTMIDataParams;
	pDataParams->pTmpBuffer				= pTmpBuffer;
	pDataParams->wTmpBufSize			= wTmpBufSize;
    pDataParams->bAuthMode				= PHAL_MFDFEVX_NOT_AUTHENTICATED;
    pDataParams->bKeyNo					= 0xFF;
    pDataParams->bWrappedMode			= PH_OFF;
    pDataParams->wAdditionalInfo		= 0x0000;
	pDataParams->bCmdCode				= PHAL_MFDFEVX_CMD_INVALID;

    /* Default selected application */
    memset(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid, 0x00, 3); /* PRQA S 3200 */

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}




/* MIFARE DESFire EVx secure messaging related commands. ------------------------------------------------------------------------------- */
phStatus_t phalMfdfEVx_Sam_X_Authenticate(void * pDataParams, uint16_t wOption, uint16_t wKeyNo, uint16_t wKeyVer, uint8_t bKeyNoCard, uint8_t * pDivInput, uint8_t bDivInputLen)
{
    phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bISOMode = 0;
	uint8_t     PH_MEMLOC_REM bAuthMode = 0;

    /* Check for CardKeyNo. */
	if ((bKeyNoCard & 0x0F) > 0x0D)
    {
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    /* Check for valid SAM keystore number and version. */
    if ((wKeyNo > 0x7f) || (wKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Change for valid diversification options. */
	if ((wOption != PHAL_MFDFEVX_NO_DIVERSIFICATION) &&
		(wOption != (PH_CRYPTOSYM_DIV_MODE_DESFIRE | PH_CRYPTOSYM_DIV_OPTION_2K3DES_HALF)) &&
		(wOption != (PH_CRYPTOSYM_DIV_MODE_DESFIRE | PH_CRYPTOSYM_DIV_OPTION_2K3DES_FULL)) &&        
		(wOption != PH_CRYPTOSYM_DIV_MODE_MIFARE_PLUS))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	/* Validate diversification input length. */
	if ((wOption != PHAL_MFDFEVX_NO_DIVERSIFICATION) && (bDivInputLen > 31 ))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	/* Clear the PICC status code buffer. */
	memset(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode, 0x00, 
		sizeof(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));	/* PRQA S 3200 */

	/* Set Auth mode with diversification enabled. */
	bAuthMode = (uint8_t) ((wOption != PHAL_MFDFEVX_NO_DIVERSIFICATION) ? PHHAL_HW_CMD_SAMAV3_KEY_DIVERSIFICATION_ON : 
		PHHAL_HW_CMD_SAMAV3_KEY_DIVERSIFICATION_OFF);
	
	/* Set Diversification flags. 
	 * For AV1 compatibility mode key diversification methods, TDEA Key, diversified using one encryption round
	 */
    if (wOption == PH_CRYPTOSYM_DIV_OPTION_2K3DES_HALF)
    {
        bAuthMode = (uint8_t) (bAuthMode | PHHAL_HW_CMD_SAMAV3_KDF_AV1_SINGLE_ENCRYPTION);
	}

	/* Set Diversification flags. 
	 * AV2 compatibility mode key diversification methods, 3TDEA, AES key
	 */
    if (wOption == PH_CRYPTOSYM_DIV_MODE_MIFARE_PLUS)
    {
        bAuthMode = (uint8_t) (bAuthMode | PHHAL_HW_CMD_SAMAV3_KDF_AV2);
	}

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_AUTHENTICATE;

    /* Unset the current authentication status. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode = PHAL_MFDFEVX_NOT_AUTHENTICATED;
    PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bKeyNo = 0xFF;

    /* Set Native or ISO7816 PICC command format. */
    bISOMode = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode? PHHAL_HW_CMD_SAMAV3_ISO_MODE_ISO7816 : 
		PHHAL_HW_CMD_SAMAV3_ISO_MODE_NATIVE);

	/* Exchange the information to SAM. */
    wStatus = phhalHw_SamAV3_Cmd_DESFire_AuthenticatePICC(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
        bAuthMode,
        bISOMode,
        bKeyNoCard,
        (uint8_t) wKeyNo,
        (uint8_t) wKeyVer,
		0,
		NULL,
        pDivInput,
        bDivInputLen,
		NULL,
		NULL,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode = PHAL_MFDFEVX_AUTHENTICATE;
    PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bKeyNo = bKeyNoCard;

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_AuthenticateISO(void * pDataParams, uint16_t wOption, uint16_t wKeyNo, uint16_t wKeyVer, uint8_t bKeyNoCard, uint8_t * pDivInput, uint8_t bDivInputLen)
{
    phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bISOMode = 0;
	uint8_t     PH_MEMLOC_REM bAuthMode = 0;

	/* Check for CardKeyNo. */
	if ((bKeyNoCard & 0x0F) > 0x0D)
    {
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    /* Check for valid SAM keystore number and version. */
    if ((wKeyNo > 0x7f) || (wKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Change for valid diversification options. */
	if ((wOption != PHAL_MFDFEVX_NO_DIVERSIFICATION) &&
		(wOption != (PH_CRYPTOSYM_DIV_MODE_DESFIRE | PH_CRYPTOSYM_DIV_OPTION_2K3DES_HALF)) &&
		(wOption != (PH_CRYPTOSYM_DIV_MODE_DESFIRE | PH_CRYPTOSYM_DIV_OPTION_2K3DES_FULL)) &&        
		(wOption != PH_CRYPTOSYM_DIV_MODE_MIFARE_PLUS))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	/* Validate diversification input length. */
	if ((wOption != PHAL_MFDFEVX_NO_DIVERSIFICATION) && (bDivInputLen > 31 ))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	/* Clear the PICC status code buffer. */
	memset(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode, 0x00, 
		sizeof(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));	/* PRQA S 3200 */
	
	/* Set Auth mode with diversification enabled. */
	bAuthMode = (uint8_t) ((wOption != PHAL_MFDFEVX_NO_DIVERSIFICATION) ? PHHAL_HW_CMD_SAMAV3_KEY_DIVERSIFICATION_ON : 
		PHHAL_HW_CMD_SAMAV3_KEY_DIVERSIFICATION_OFF);
	
	/* Set Diversification flags. 
	 * For AV1 compatibility mode key diversification methods, TDEA Key, diversified using one encryption round
	 */
    if (wOption == PH_CRYPTOSYM_DIV_OPTION_2K3DES_HALF)
    {
        bAuthMode = (uint8_t) (bAuthMode | PHHAL_HW_CMD_SAMAV3_KDF_AV1_SINGLE_ENCRYPTION);
	}

	/* Set Diversification flags. 
	 * AV2 compatibility mode key diversification methods, 3TDEA, AES key
	 */
    if (wOption == PH_CRYPTOSYM_DIV_MODE_MIFARE_PLUS)
    {
        bAuthMode = (uint8_t) (bAuthMode | PHHAL_HW_CMD_SAMAV3_KDF_AV2);
	}

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_AUTHENTICATE_ISO;

    /* Unset the current authentication status. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode = PHAL_MFDFEVX_NOT_AUTHENTICATED;
    PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bKeyNo = 0xFF;

    /* Set Native or ISO7816 PICC command format. */
    bISOMode = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode? PHHAL_HW_CMD_SAMAV3_ISO_MODE_ISO7816 : 
		PHHAL_HW_CMD_SAMAV3_ISO_MODE_NATIVE);

	/* Exchange the information to SAM. */
    wStatus = phhalHw_SamAV3_Cmd_DESFire_AuthenticatePICC(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
        bAuthMode,
        bISOMode,
        bKeyNoCard,
        (uint8_t) wKeyNo,
        (uint8_t) wKeyVer,
		0,
		NULL,
        pDivInput,
        bDivInputLen,
		NULL,
		NULL,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode = PHAL_MFDFEVX_AUTHENTICATEISO;
    PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bKeyNo = bKeyNoCard;

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_AuthenticateAES(void * pDataParams, uint16_t wOption, uint16_t wKeyNo, uint16_t wKeyVer, uint8_t bKeyNoCard, uint8_t * pDivInput, uint8_t bDivInputLen)
{
    phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bISOMode = 0;
	uint8_t     PH_MEMLOC_REM bAuthMode = 0;
	uint8_t		PH_MEMLOC_REM aAppId[3] = {0x00, 0x00, 0x00};

    /* Check for CardKeyNo. */
	if ((bKeyNoCard & 0x0F) > 0x0D)
    {
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    /* Check for valid SAM keystore number and version. */
    if ((wKeyNo > 0x7f) || (wKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Change for valid diversification options. */
	if ((wOption != PHAL_MFDFEVX_NO_DIVERSIFICATION) &&
		(wOption != (PH_CRYPTOSYM_DIV_MODE_DESFIRE | PH_CRYPTOSYM_DIV_OPTION_2K3DES_FULL)) &&        
		(wOption != PH_CRYPTOSYM_DIV_MODE_MIFARE_PLUS))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	/* Validate diversification input length. */
	if ((wOption != PHAL_MFDFEVX_NO_DIVERSIFICATION) && (bDivInputLen > 31 ))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	/* Clear the PICC status code buffer. */
	memset(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode, 0x00, 
		sizeof(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));	/* PRQA S 3200 */

	/* Set Auth mode with diversification enabled. */
	bAuthMode = (uint8_t) ((wOption != PHAL_MFDFEVX_NO_DIVERSIFICATION) ? PHHAL_HW_CMD_SAMAV3_KEY_DIVERSIFICATION_ON : 
		PHHAL_HW_CMD_SAMAV3_KEY_DIVERSIFICATION_OFF);

	/* Set Diversification flags. 
	 * AV2 compatibility mode key diversification methods, 3TDEA, AES key
	 */
    if (wOption == PH_CRYPTOSYM_DIV_MODE_MIFARE_PLUS)
    {
        bAuthMode = (uint8_t) (bAuthMode | PHHAL_HW_CMD_SAMAV3_KDF_AV2);
	}

	/* Set the secure messaging. */
	if((bKeyNoCard >= PHAL_MFDFEVX_ORIGINALITY_KEY_FIRST) && (bKeyNoCard <= PHAL_MFDFEVX_ORIGINALITY_KEY_LAST) &&
		(memcmp(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid, aAppId, 3) == 0x00))
	{
		bAuthMode = (uint8_t) (bAuthMode | PHHAL_HW_CMD_SAMAV3_SUPPRESS_SECURE_MESSAGING);
	}

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_AUTHENTICATE_AES;

    /* Unset the current authentication status. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode = PHAL_MFDFEVX_NOT_AUTHENTICATED;
    PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bKeyNo = 0xFF;

    /* Set Native or ISO7816 PICC command format. */
    bISOMode = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode? PHHAL_HW_CMD_SAMAV3_ISO_MODE_ISO7816 : 
		PHHAL_HW_CMD_SAMAV3_ISO_MODE_NATIVE);

	/* Exchange the information to SAM. */
    wStatus = phhalHw_SamAV3_Cmd_DESFire_AuthenticatePICC(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
        bAuthMode,
        bISOMode,
        bKeyNoCard,
        (uint8_t) wKeyNo,
        (uint8_t) wKeyVer,
		0,
		NULL,
        pDivInput,
        bDivInputLen,
		NULL,
		NULL,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	/* Update the authentication states. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode = PHAL_MFDFEVX_AUTHENTICATEAES;
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bKeyNo = bKeyNoCard;

	/* Do not update the auth state if originality keys are used. */
	if((bKeyNoCard >= PHAL_MFDFEVX_ORIGINALITY_KEY_FIRST) && (bKeyNoCard <= PHAL_MFDFEVX_ORIGINALITY_KEY_LAST) &&
		(memcmp(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid, aAppId, 3) == 0x00))
	{
		PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_ResetAuthStatus(pDataParams));
	}

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_AuthenticateEv2(void *pDataParams, uint8_t bFirstAuth, uint16_t wOption, uint16_t wKeyNo, uint16_t wKeyVer, uint8_t bKeyNoCard, uint8_t * pDivInput,
	uint8_t bDivInputLen, uint8_t * pPcdCapsIn, uint8_t bPcdCapsInLen, uint8_t * pPcdCapsOut, uint8_t * pPdCapsOut)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bISOMode = 0;
	uint8_t     PH_MEMLOC_REM bAuthMode = 0;
	uint8_t		PH_MEMLOC_REM aAppId[3] = {0x00, 0x00, 0x00};

	/* Validate auth type. */
	if (bFirstAuth > 0x01)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Check for CardKeyNo. */
	if ((bKeyNoCard & 0x0F) > 0x0D)
    {
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    /* Validate SAM Key number and version. */
    if ((wKeyNo > 0x7f) || (wKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Validate Diversification options. */
	if ((wOption != PHAL_MFDFEVX_NO_DIVERSIFICATION) &&
		(wOption != (PH_CRYPTOSYM_DIV_MODE_DESFIRE | PH_CRYPTOSYM_DIV_OPTION_2K3DES_FULL)) &&        
		(wOption != PH_CRYPTOSYM_DIV_MODE_MIFARE_PLUS))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	/* Validate diversification input length. */
	if ((wOption != PHAL_MFDFEVX_NO_DIVERSIFICATION) && (bDivInputLen > 31 ))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	/* Clear the PICC status code buffer. */
	memset(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode, 0x00, 
		sizeof(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));	/* PRQA S 3200 */

	/*
	 * Set EV2 Authentication type.
	 * EV2 authentication type
	 * Authenticate first
	 * Authenticate non first
	 * AV2 compatibility mode key diversification methods, 3TDEA, AES key
	 */
	bAuthMode = (uint8_t) ((bFirstAuth ? PHHAL_HW_CMD_SAMAV3_AUTH_MODE_EV2_FIRST_AUTH : PHHAL_HW_CMD_SAMAV3_AUTH_MODE_EV2_NON_FIRST_AUTH));

	/* Set Auth mode with diversification enabled. */
	bAuthMode = (uint8_t) (bAuthMode | ((wOption != PHAL_MFDFEVX_NO_DIVERSIFICATION) ? PHHAL_HW_CMD_SAMAV3_KEY_DIVERSIFICATION_ON : 
		PHHAL_HW_CMD_SAMAV3_KEY_DIVERSIFICATION_OFF));

	/* Set Diversification flags. 
	 * AV2 compatibility mode key diversification methods, 3TDEA, AES key
	 */
    if (wOption == PH_CRYPTOSYM_DIV_MODE_MIFARE_PLUS)
    {
        bAuthMode = (uint8_t) (bAuthMode | PHHAL_HW_CMD_SAMAV3_KDF_AV2);
	}

	/* Set the secure messaging. */
	if((bKeyNoCard >= PHAL_MFDFEVX_ORIGINALITY_KEY_FIRST) && (bKeyNoCard <= PHAL_MFDFEVX_ORIGINALITY_KEY_LAST) &&
		(memcmp(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid, aAppId, 3) == 0x00))
	{
		bAuthMode = (uint8_t) (bAuthMode | PHHAL_HW_CMD_SAMAV3_SUPPRESS_SECURE_MESSAGING);
	}

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = (uint8_t) ((bFirstAuth ? PHAL_MFDFEVX_CMD_AUTHENTICATE_EV2_FIRST : 
		PHAL_MFDFEVX_CMD_AUTHENTICATE_EV2_NON_FIRST));

    /* Unset the current authentication status */
    PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode = PHAL_MFDFEVX_NOT_AUTHENTICATED;
    PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bKeyNo = 0xFF;

    /* Set Native or ISO7816 PICC command format. */
    bISOMode = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode? PHHAL_HW_CMD_SAMAV3_ISO_MODE_ISO7816 : 
		PHHAL_HW_CMD_SAMAV3_ISO_MODE_NATIVE);

    wStatus = phhalHw_SamAV3_Cmd_DESFire_AuthenticatePICC(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
        bAuthMode,
        bISOMode,
        bKeyNoCard,
        (uint8_t) wKeyNo,
        (uint8_t) wKeyVer,
		bPcdCapsInLen,
		bPcdCapsInLen ? pPcdCapsIn : NULL,
        pDivInput,
        bDivInputLen,
		pPdCapsOut,
		pPcdCapsOut,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	/* Update the authentication states. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode = PHAL_MFDFEVX_AUTHENTICATEEV2;
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bKeyNo = bKeyNoCard;

	/* Do not update the auth state if originality keys are used. */
	if((bKeyNoCard >= PHAL_MFDFEVX_ORIGINALITY_KEY_FIRST) && (bKeyNoCard <= PHAL_MFDFEVX_ORIGINALITY_KEY_LAST) &&
		(memcmp(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid, aAppId, 3) == 0x00))
	{
		PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_ResetAuthStatus(pDataParams));
	}

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}




/* MIFARE DESFire EVx Memory and Configuration mamangement commands. ------------------------------------------------------------------- */
phStatus_t phalMfdfEVx_Sam_X_FreeMem(void * pDataParams, uint8_t * pMemInfo)
{
    phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_FREE_MEM;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_FREE_MEM;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	/* Copy the data to the parameter */
	memcpy(pMemInfo, pResponse, wRespLen);	/* PRQA S 3200 */

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_FormatPICC(void * pDataParams)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_FORMAT;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_FORMAT;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_SetConfiguration(void * pDataParams, uint8_t bOption, uint8_t * pData, uint8_t bDataSize)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
	uint8_t		PH_MEMLOC_REM bLenPresent = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	
	if (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_NOT_AUTHENTICATED)
	{
		return PH_ADD_COMPCODE(PH_ERR_USE_CONDITION, PH_COMP_AL_MFDFEVX);
	}

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the Length and Crypto information. */
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		/* Start of data. */
		pAppData[wAppDataLen++] = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? 6 : 2);

		/* Set Extended Offset in Crypto mode. */
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_EXTENDED_OFFSET;

		/* Set Length Presence flag. */
		bLenPresent = PH_ON;
	}

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_SET_CONFIG;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_SET_CONFIG;
	pAppData[wAppDataLen++] = bOption;

    memcpy(&pAppData[wAppDataLen], pData, bDataSize); /* PRQA S 3200 */
	wAppDataLen = (uint16_t) (wAppDataLen + bDataSize);

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		bLenPresent,
		1,
		PH_OFF,
		0,
		pAppData,
		&wAppDataLen));
		
	/* Frame the Crypto information. */
	bCrypto |= PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_FULL;

	/* Set the Command Offset. */
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode != PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = (uint8_t) (bCrypto + (wAppDataLen - bDataSize));
	}

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_GetVersion(void * pDataParams, uint8_t * pVerInfo)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;
	uint8_t		PH_MEMLOC_REM bVerLen = 0;
	uint8_t		PH_MEMLOC_REM bFinished = 0;

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_GET_VERSION;

	do
	{
		/* Wrap the command if required. */
		PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
			pDataParams,
			PH_ON,
			PH_OFF,
			0,
			PH_ON,
			0,
			pAppData,
			&wAppDataLen));

		/* Exchange the information to Sam. */
		wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
			PH_EXCHANGE_DEFAULT,
			bCrypto,
			pAppData,
			(uint8_t) wAppDataLen,
			&pResponse,
			&wRespLen,
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
			&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

		/* Evaluate the response. */
		wStatus = phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode);
				
		/* Updated Finished to end the loop. */
		if(((wStatus & PH_ERR_MASK) != PH_ERR_SUCCESS_CHAINING) && ((wStatus & PH_ERR_MASK) != PH_ERR_SUCCESS))
		{
			PH_CHECK_SUCCESS(wStatus);
		}
		else
		{
			/* Update Command frame. */
			wAppDataLen = 0;
			pAppData[wAppDataLen++] = 0xAF;
				
			/* Copy the response information to the parameter. */
			memcpy(&pVerInfo[bVerLen], pResponse, wRespLen); /* PRQA S 3200 */
			bVerLen = (uint8_t) (bVerLen + wRespLen);

			/* Update Finish flag. */
			if((wStatus & PH_ERR_MASK) == PH_ERR_SUCCESS)
			{
				bFinished = 1;
			}
		}
	}while(!bFinished);

	/* Do a Set Config of ADDITIONAL_INFO to set  the length(wLength) of the Version string */
	phalMfdfEVx_Sam_X_SetConfig(pDataParams, PHAL_MFDFEVX_ADDITIONAL_INFO, bVerLen);

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_GetCardUID(void * pDataParams, uint8_t bExchangeOption, uint8_t bOption, uint8_t * pUid, uint8_t * pUidLen)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
	uint8_t     PH_MEMLOC_REM bUidLen = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;
	uint8_t		PH_MEMLOC_REM bUidOffset = 0;

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Check if UID length is provided. */
	bUidLen = (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wAdditionalInfo != 4) &&
						 (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wAdditionalInfo != 7) &&
						 (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wAdditionalInfo != 10) ? 7 : 
						 PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wAdditionalInfo);

	/* Append expected length to the command frame. */
	pAppData[wAppDataLen++] = bUidLen;
	pAppData[wAppDataLen++] = 0;
	pAppData[wAppDataLen++] = 0;
	
	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_GET_CARD_UID;

	if (bExchangeOption)
	{
		pAppData[wAppDataLen++] = bOption;

		/* Update UID Length if there is NUID available. */
		pAppData[0] = (uint8_t) ((bOption == PHAL_MFDFEVX_GET_CARD_UID_OPTION_NUID_RETURNED) ? (bUidLen + 4) : bUidLen);
	}

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_ON,
		3,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));
		
	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_FULL;

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	/* Response will be received as
	* 1. 7 byte UID
	* 2. [1 Byte UID Format] + [1 byte UID Length(0x04)] + 4 byte UID
	* 3. [1 Byte UID Format] + [1 byte UID Length(0x0A)] + 10 byte UID
	*/
	if (!bExchangeOption)
	{
		if (((wRespLen != PHAL_MFDFEVX_DEFAULT_UID_LENGTH) &&
			(wRespLen != PHAL_MFDFEVX_10B_UID_LENGTH) &&
			(wRespLen != PHAL_MFDFEVX_4B_UID_LENGTH)))
		{
			return PH_ADD_COMPCODE(PH_ERR_PROTOCOL_ERROR, PH_COMP_AL_MFDFEVX);
		}
	}

	if (((wRespLen == PHAL_MFDFEVX_10B_UID_LENGTH) || (wRespLen == PHAL_MFDFEVX_4B_UID_LENGTH)) && !bExchangeOption)
	{
		/* In case of 4B/10B UID, strip out first 2 bytes as it contains UID format and UID length */
		wRespLen -= 2;

		*pUidLen = (uint8_t) wRespLen;

		/* Validate UIDFormat (0x00) for 4byte and 7Byte UID and UIDLength to be equal to real UID */
		if ((pUid[0] != 0x00) | (pUid[1] != *pUidLen))
		{
			return PH_ADD_COMPCODE(PH_ERR_PROTOCOL_ERROR, PH_COMP_AL_MFDFEVX);
		}
		memcpy(pUid, &pUid[2], *pUidLen);
	}
	else
	{
		*pUidLen = (uint8_t) wRespLen;

		/* Compute the UIDOffset. */
		bUidOffset = (uint8_t)(((wRespLen == PHAL_MFDFEVX_DEFAULT_UID_LENGTH) || (wRespLen == (PHAL_MFDFEVX_DEFAULT_UID_LENGTH + 4))) ? 0 : 2);
	}

	/* Update the UID information to the dataparams. */
	memcpy(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bUid, &pUid[bUidOffset], *pUidLen - bUidOffset);
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bUidLength = *pUidLen - bUidOffset;
		
	/* Set the card Length in wAdditionalInfo. This is done to assist C# wrapper as it will not be able
	 * to recognize the card UID Length.
	 */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_SetConfig(pDataParams, PHAL_MFDFEVX_ADDITIONAL_INFO, wRespLen));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}




/* MIFARE DESFire EVx Key mamangement commands. ---------------------------------------------------------------------------------------- */
phStatus_t phalMfdfEVx_Sam_X_ChangeKey(void * pDataParams, uint16_t wOption, uint16_t wOldKeyNo, uint16_t wOldKeyVer, uint16_t wNewKeyNo, uint16_t wNewKeyVer, uint8_t bKeyNoCard,
	uint8_t * pDivInput, uint8_t bDivInputLen)
{
    phStatus_t  PH_MEMLOC_REM wStatus = 0;
    phStatus_t  PH_MEMLOC_REM wStatus1 = 0;
    uint8_t     PH_MEMLOC_REM bKeyCompMeth = 0;
    uint8_t     PH_MEMLOC_REM bCfg = 0;
    uint8_t     PH_MEMLOC_REM bISOMode = 0;
	uint8_t		PH_MEMLOC_REM aAppId[3] = {0x00, 0x00, 0x00};

	/* Only if seleted Aid is 0x000000. */
	if(memcmp(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid, aAppId, 3) == 0x00)
    {
		/* Master key */
        if((bKeyNoCard & 0x3F) != 0x00)
        {
            /* Invalid card key number supplied */
            return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
        }
		else
		{
			/*Do Nothing. This is for PRQA compliance */
		}
    }
    else
    {
        if (bKeyNoCard > 0x0D)
        {
            /* Invalid application key specified */
            return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
        }
    }

    /* Check for valid SAM key number and version. */
    if ((wOldKeyNo > 0x7f) || (wOldKeyVer > 0xff) || (wNewKeyNo > 0x7f) || (wNewKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Clear the PICC status code buffer. */
	memset(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode, 0x00, 
		sizeof(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_CHANGE_KEY;
	
    /* Set Native or ISO7816 PICC command format. */
    bISOMode = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode? PHHAL_HW_CMD_SAMAV3_ISO_MODE_ISO7816 : 
		PHHAL_HW_CMD_SAMAV3_ISO_MODE_NATIVE);

    /* Set the key compilation method. */
	if(wOption == PHAL_MFDFEVX_NO_DIVERSIFICATION)
	{
		bKeyCompMeth = 0x00;
	}
	else
	{
		/* Validate diversification input length. */
		if ( bDivInputLen > 31 )
		{
			return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
		}

		/* Validate option information. */
		if(!(wOption & 0x003E))
		{
			return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
		}

		/* Assin the option to local variable. */
		bKeyCompMeth = (uint8_t) wOption;
	}
   
    /* DESFire key number to be changed. */
	bCfg = (uint8_t) (0x0f & bKeyNoCard);

    /* Set if PICC targeted key equal to PICC authenticated key. */
    if ((bKeyNoCard & 0x3f) == 0)
    {
        bKeyCompMeth = (uint8_t) (bKeyCompMeth | PHHAL_HW_CMD_SAMAV3_CRYPTO_MODE_SAME_KEY);
    }

    /* Include the key type in the cryptogram for Master Key */
    if(memcmp(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid, aAppId, 3) == 0x00)
    {
        bCfg = (uint8_t) (bCfg | PHHAL_HW_CMD_SAMAV3_MASTER_KEY_UPDATE_INCLUDE_KEYTYPE);
    }

	/* Enable Iso7816 wrapping. */
    bCfg = (uint8_t) (bCfg | bISOMode);

	/* Exchange the command to PICC. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ChangeKeyPICC(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		bKeyCompMeth,
		bCfg,
		0x00,
		0x00,
		(uint8_t)wOldKeyNo,
		(uint8_t)wOldKeyVer,
		(uint8_t)wNewKeyNo,
		(uint8_t)wNewKeyVer,
		pDivInput,
		bDivInputLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode);

    /* Evaluate the response. */
	wStatus = phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode);

	/* Reset the Auth state. */
	if(wStatus != PH_ERR_SUCCESS)
	{
		if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode != PHAL_MFDFEVX_AUTHENTICATE)
		{
			PH_CHECK_SUCCESS_FCT(wStatus1, phalMfdfEVx_Sam_X_ResetAuthStatus(pDataParams));
		}

		return wStatus;
	}
	else
	{
		/* Reset authentication status only if the key authenticated with is changed. */
		if (((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bKeyNo & 0x3FU) == (bKeyNoCard & 0x3FU)))
		{
			PH_CHECK_SUCCESS_FCT(wStatus1, phalMfdfEVx_Sam_X_ResetAuthStatus(pDataParams));
		}
	}

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_ChangeKeyEv2(void * pDataParams, uint16_t wOption, uint16_t wOldKeyNo, uint16_t wOldKeyVer, uint16_t wNewKeyNo, uint16_t wNewKeyVer, uint8_t bKeySetNo,
	uint8_t bKeyNoCard, uint8_t * pDivInput, uint8_t bDivInputLen)
{
    phStatus_t  PH_MEMLOC_REM wStatus = 0;
    phStatus_t  PH_MEMLOC_REM wStatus1 = 0;
    uint8_t     PH_MEMLOC_REM bKeyCompMeth = 0;
    uint8_t     PH_MEMLOC_REM bCfg = 0;
    uint8_t     PH_MEMLOC_REM bISOMode = 0;
	uint8_t		PH_MEMLOC_REM aAppId[3] = {0x00, 0x00, 0x00};

    /* Only if seleted Aid is 0x000000. */
	if(memcmp(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid, aAppId, 3) == 0x00)
    {
			/* PICC Master key */
        if (((bKeyNoCard & 0x3F) != 0x00) &&
			
			/* PICC DAMAuthKey, DAMMACKey, DAMEncKey */
            ((bKeyNoCard & 0x3F) != 0x10) && ((bKeyNoCard & 0x3F) != 0x11) && ((bKeyNoCard & 0x3F) != 0x12) &&

			/* PICC NXPDAMAuthKey, NXPDAMMACKey, NXPDAMEncKey */
			((bKeyNoCard & 0x3F) != 0x18) && ((bKeyNoCard & 0x3F) != 0x19) && ((bKeyNoCard & 0x3F) != 0x1A) &&

			/* PICC VCConfigurationKey, VCProximityKey, VCSelectMACKey, VCSelectENCKey */
            ((bKeyNoCard & 0x3F) != 0x20) && ((bKeyNoCard & 0x3F) != 0x21) && ((bKeyNoCard & 0x3F) != 0x22) && ((bKeyNoCard & 0x3F) != 0x23) &&

			/* PICC VCPollingEncKey, VCPollingMACKey */
            ((bKeyNoCard & 0x3F) != 0x30) && ((bKeyNoCard & 0x3F) != 0x31) &&

			/* MFCKillKey, MFCLicenseMACKey */
			((bKeyNoCard & 0x3F) != 0x31) && ((bKeyNoCard & 0x3F) != 0x32))
        {
            /* Invalid card key number supplied */
            return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
        }
		else
		{
			/*Do Nothing. This is for PRQA compliance */
		}
    }
    else
    {
        /* Key numbers between 0D and 21 are not allowed for App level, also key numbers above 23 are not allowed.
		   if AID 0x000000 is not selected,At application level, VC keys 0x21, 0x22 and 0x23 can be enabled at application creation,
		   Refer reference architecture version 13 */
        if (IS_INVALID_APP_KEY(bKeyNoCard) || IS_INVALID_VC_KEY(bKeyNoCard))
        {
            /* Invalid application key specified */
            return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
        }
    }

	/* Validate Keyset number. */
	if (bKeySetNo > 0x0F)
    {
        /* Invalid KeySetNo specified */
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    /* Check for valid SAM key number and version. */
    if ((wOldKeyNo > 0x7f) || (wOldKeyVer > 0xff) || (wNewKeyNo > 0x7f) || (wNewKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Clear the PICC status code buffer. */
	memset(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode, 0x00, 
		sizeof(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_CHANGE_KEY_EV2;
	
    /* Set Native or ISO7816 PICC command format. */
    bISOMode = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode? PHHAL_HW_CMD_SAMAV3_ISO_MODE_ISO7816 : 
		PHHAL_HW_CMD_SAMAV3_ISO_MODE_NATIVE);

    /* Set the key compilation method. */
	if(wOption == PHAL_MFDFEVX_NO_DIVERSIFICATION)
	{
		bKeyCompMeth = 0x00;
	}
	else
	{
		/* Validate diversification input length. */
		if ( bDivInputLen > 31 )
		{
			return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
		}

		/* Validate option information. */
		if(!(wOption & 0x003E))
		{
			return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
		}

		/* Assing the option to local variable. */
		bKeyCompMeth = (uint8_t) wOption;
	}

    /* Set if PICC targeted key equal to PICC authenticated key. */
    if ((bKeyNoCard & 0x3f) == 0)
    {
        bKeyCompMeth = (uint8_t) (bKeyCompMeth | PHHAL_HW_CMD_SAMAV3_CRYPTO_MODE_SAME_KEY);
    }

	/* Set EV2 ChangeKey type. */
	bCfg = (uint8_t) (bCfg | PHHAL_HW_CMD_SAMAV3_CMD_TYPE_CHANGE_KEY_EV2);

    /* Include the key type in the cryptogram for Master Key */
    if((memcmp(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid, aAppId, 3) == 0x00) &&
		((bKeyNoCard & 0x3F) == 0x00))
    {
        bCfg = (uint8_t) (bCfg | PHHAL_HW_CMD_SAMAV3_MASTER_KEY_UPDATE_INCLUDE_KEYTYPE);
    }

	/* Enable Iso7816 wrapping. */
    bCfg = (uint8_t) (bCfg | bISOMode);

	/* Exchange the command to PICC. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ChangeKeyPICC(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		bKeyCompMeth,
		bCfg,
		bKeySetNo,
		(uint8_t) (bKeyNoCard & 0x3F),
		(uint8_t) wOldKeyNo,
		(uint8_t) wOldKeyVer,
		(uint8_t) wNewKeyNo,
		(uint8_t) wNewKeyVer,
		pDivInput,
		bDivInputLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	/* Reset the Auth state. */
	if(wStatus != PH_ERR_SUCCESS)
	{
		if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode != PHAL_MFDFEVX_AUTHENTICATE)
		{
			PH_CHECK_SUCCESS_FCT(wStatus1, phalMfdfEVx_Sam_X_ResetAuthStatus(pDataParams));
		}

		return wStatus;
	}
	else
	{
		/* Reset authentication status only if the key authenticated with is changed. */
		if (((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bKeyNo & 0x3FU) == (bKeyNoCard & 0x3FU)) && ((bKeySetNo & 0x0F) == 0))
		{
			PH_CHECK_SUCCESS_FCT(wStatus1, phalMfdfEVx_Sam_X_ResetAuthStatus(pDataParams));
		}
	}

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_InitializeKeySet(void * pDataParams, uint8_t bKeySetNo, uint8_t bKeyType)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	
	/* Validate the parameters. */
	if (((bKeySetNo & 0x7f) > 0x0f) || (bKeyType > PHAL_MFDFEVX_KEY_TYPE_AES128))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_INITIALIZE_KEY_SET;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_INITIALIZE_KEY_SET;
	pAppData[wAppDataLen++] = bKeySetNo;
	pAppData[wAppDataLen++] = bKeyType;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_OFF,
		0,
		pAppData,
		&wAppDataLen));
		
	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	
	if((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEAES) ||
	   (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEISO) ||
	   ( PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_FinalizeKeySet(void * pDataParams, uint8_t bKeySetNo, uint8_t bKeyVersion)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	
	/* Validate the parameters */
	if ((bKeySetNo & 0x7f) > 0x0f)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_FINALIZE_KEY_SET;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_FINALIZE_KEY_SET;
	pAppData[wAppDataLen++] = bKeySetNo;
	pAppData[wAppDataLen++] = bKeyVersion;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_OFF,
		0,
		pAppData,
		&wAppDataLen));
		
	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	
	if((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEAES) ||
	   (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEISO) ||
	   ( PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_RollKeySet(void * pDataParams, uint8_t bKeySetNo )
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	
	/* Validate parameters */
	if ((bKeySetNo & 0x7f) > 0x0f)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_ROLL_KEY_SET;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_ROLL_KEY_SET;
	pAppData[wAppDataLen++] = bKeySetNo;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_OFF,
		0,
		pAppData,
		&wAppDataLen));
		
	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	
	if((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEAES) ||
	   (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEISO) ||
	   ( PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	/* Reset the states. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_ResetAuthStatus(pDataParams));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_GetKeySettings(void * pDataParams, uint8_t * pKeySetting, uint8_t * pKeySettingLen)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_GET_KEY_SETTINGS;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_GET_KEY_SETTINGS;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	/* Copy the data to the parameter */
	memcpy(pKeySetting, pResponse, wRespLen);	/* PRQA S 3200 */
	*pKeySettingLen = (uint8_t) wRespLen;

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_ChangeKeySettings(void * pDataParams, uint8_t bKeySettings)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
	uint8_t		PH_MEMLOC_REM bLenPresent = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_CHANGE_KEY_SETTINGS;
	
	/* Set the Length and Crypto information. */
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		/* Start of data. */
		pAppData[wAppDataLen++] = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? 5 : 1);

		/* Set Extended Offset in Crypto mode. */
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_EXTENDED_OFFSET;

		/* Set Length Presence flag. */
		bLenPresent = PH_ON;
	}
	
	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_CHANGE_KEY_SETTINGS;
	pAppData[wAppDataLen++] = bKeySettings;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		bLenPresent,
		1,
		PH_OFF,
		0,
		pAppData,
		&wAppDataLen));
		
	/* Frame the Crypto information. */
	bCrypto |= PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_FULL;

	/* Set the Command Offset. */
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode != PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = (uint8_t) (bCrypto + (wAppDataLen - 1));
	}

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_GetKeyVersion(void * pDataParams, uint8_t bKeyNo, uint8_t bKeySetNo, uint8_t * pKeyVersion, uint8_t * pKeyVerLen)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	 /* Only if seleted Aid is 0x000000. */
	if ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid[0] != 0) &&
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid[1] != 0) &&
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid[2] != 0) &&
		((bKeyNo & 0x0F) > 0x0D))
    {
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_GET_KEY_VERSION;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_GET_KEY_VERSION;
	pAppData[wAppDataLen++] = bKeyNo;

	/* Add KeySet number if set in KeyNo bit 6. */
	if(bKeyNo & PHAL_MFDFEVX_KEYSETVERSIONS)
	{
		pAppData[wAppDataLen++] = bKeySetNo;
	}

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	/* Copy the data to the parameter */
	memcpy(pKeyVersion, pResponse, wRespLen);	/* PRQA S 3200 */
	*pKeyVerLen = (uint8_t) wRespLen;

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}




/* MIFARE DESFire EVx Application mamangement commands. -------------------------------------------------------------------------------- */
phStatus_t phalMfdfEVx_Sam_X_CreateApplication(void * pDataParams, uint8_t bOption, uint8_t * pAid, uint8_t bKeySettings1, uint8_t bKeySettings2, uint8_t bKeySettings3,
	uint8_t * pKeySetValues, uint8_t * pISOFileId, uint8_t * pISODFName, uint8_t bISODFNameLen)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Check for valid ISO DFName */
    if ((bISODFNameLen > 16) || (bOption == 0x02) || (bOption > 0x03))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_CREATE_APPLN;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_CREATE_APPLN;

	/* Buffer Application identifier to the command frame. */
    memcpy(&pAppData[wAppDataLen], pAid, 3); /* PRQA S 3200 */
	wAppDataLen += 3;

	/* Buffer Key settings information to command frame. */
    pAppData[wAppDataLen++] = bKeySettings1;
    pAppData[wAppDataLen++] = bKeySettings2;

	/* Check if KeySettings 3 to be passed */
	if (bKeySettings2 & PHAL_MFDFEVX_KEYSETT3_PRESENT)
    {
        pAppData[wAppDataLen++] = bKeySettings3;

		/* Buffer key set values if required. */
		if ((bKeySettings3 & PHAL_MFDFEVX_KEYSETVALUES_PRESENT) && pKeySetValues != NULL)
		{
			memcpy(&pAppData[wAppDataLen], pKeySetValues, 4); /* PRQA S 3200 */
			wAppDataLen += 4;
		}
    }

    /* Buffer ISO FileID to exchange buffer. */
    if ((bOption & 0x01 ) == 0x01)
    {
		pAppData[wAppDataLen++] = pISOFileId[0];
		pAppData[wAppDataLen++] = pISOFileId[1];
    }

    /* Buffer ISO DFName to exchange buffer. */
    if ((bOption & 0x02) == 0x02)
    {
		memcpy(&pAppData[wAppDataLen], pISODFName, bISODFNameLen); /* PRQA S 3200 */
		wAppDataLen += bISODFNameLen;
    }

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_DeleteApplication(void * pDataParams, uint8_t * pAid, uint8_t * pDAMMAC, uint8_t bDAMMAC_Len)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
	phStatus_t  PH_MEMLOC_REM wStatus1 = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_DELETE_APPLN;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_DELETE_APPLN;

	/* Buffer Application identifier to the command frame. */
    memcpy(&pAppData[wAppDataLen], pAid, 3); /* PRQA S 3200 */
	wAppDataLen += 3;

	/* Append the DAMMAC */
	if(bDAMMAC_Len)
	{
		memcpy(&pAppData[wAppDataLen], pDAMMAC, bDAMMAC_Len); /* PRQA S 3200 */
		wAppDataLen += bDAMMAC_Len;
	}

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

	/* Reset the states. */
	if ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid[0] == pAid[0]) &&
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid[1] == pAid[1]) &&
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid[2] == pAid[2]))
	{
		PH_CHECK_SUCCESS_FCT(wStatus1, phalMfdfEVx_Sam_X_ResetAuthStatus(pDataParams));
	}

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_CreateDelegatedApplication(void  * pDataParams, uint8_t bOption, uint8_t * pAid, uint8_t * pDamParams, uint8_t bKeySettings1, uint8_t bKeySettings2,
	uint8_t bKeySettings3, uint8_t * pKeySetValues, uint8_t * pISOFileId, uint8_t * pISODFName, uint8_t bISODFNameLen, uint8_t * pEncK, uint8_t * pDAMMAC)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
	phStatus_t  PH_MEMLOC_REM wStatus1 = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;

	/* Check for valid ISO DFName */
    if ((bISODFNameLen > 16) || (bOption == 0x02) || (bOption > 0x03))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_CREATE_DELEGATED_APPLN;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_CREATE_DELEGATED_APPLN;

	/* Buffer Application identifier to the command frame. */
    memcpy(&pAppData[wAppDataLen], pAid, 3); /* PRQA S 3200 */
	wAppDataLen += 3;

	/* Buffer DAM param to the command frame. */
	memcpy(&pAppData[wAppDataLen], pDamParams, 5); /* PRQA S 3200 */
	wAppDataLen += 5;

	/* Buffer Key settings information to command frame. */
    pAppData[wAppDataLen++] = bKeySettings1;
    pAppData[wAppDataLen++] = bKeySettings2;

	/* Check if KeySettings 3 to be passed */
	if (bKeySettings2 & PHAL_MFDFEVX_KEYSETT3_PRESENT)
    {
        pAppData[wAppDataLen++] = bKeySettings3;

		/* Buffer key set values if required. */
		if ((bKeySettings3 & PHAL_MFDFEVX_KEYSETVALUES_PRESENT) && pKeySetValues != NULL)
		{
			memcpy(&pAppData[wAppDataLen], pKeySetValues, 4); /* PRQA S 3200 */
			wAppDataLen += 4;
		}
    }

    /* Buffer ISO FileID to exchange buffer. */
    if ((bOption & 0x01 ) == 0x01)
    {
		pAppData[wAppDataLen++] = pISOFileId[0];
		pAppData[wAppDataLen++] = pISOFileId[1];
    }

    /* Buffer ISO DFName to exchange buffer. */
    if ((bOption & 0x02) == 0x02)
    {
		memcpy(&pAppData[wAppDataLen], pISODFName, bISODFNameLen); /* PRQA S 3200 */
		wAppDataLen += bISODFNameLen;
    }

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_OFF,
		0,
		pAppData,
		&wAppDataLen));
		
	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_TXCHAINING,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

	/* Check for Chaining status. */
	if((wStatus & PH_ERR_MASK) != PH_ERR_SUCCESS_CHAINING)
	{
		PH_CHECK_SUCCESS_FCT(wStatus1, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));
	}

	/* Frame second part of command information. */
	wAppDataLen = 0;
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_RESP_ADDITIONAL_FRAME;

	memcpy(&pAppData[wAppDataLen], pEncK, 32); /* PRQA S 3200 */
	wAppDataLen += 32;

	memcpy(&pAppData[wAppDataLen], pDAMMAC, 8); /* PRQA S 3200 */
	wAppDataLen += 8;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_OFF,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen));

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_SelectApplication(void * pDataParams, uint8_t bOption, uint8_t * pAppId, uint8_t * pAppId2)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_SELECT_APPLN;

	/* Reset the Auth states. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_ResetAuthStatus(pDataParams));

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_SELECT_APPLN;

	/* Add the primary application identifier */
    memcpy(&pAppData[wAppDataLen], pAppId, 3); /* PRQA S 3200 */
    wAppDataLen += 3;

	/* Add the secondary application identifier */
	if(bOption == 0x01)
	{
		memcpy(&pAppData[wAppDataLen], pAppId2, 3); /* PRQA S 3200 */
		wAppDataLen += 3;
	}

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_OFF,
		0,
		pAppData,
		&wAppDataLen));
		
	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	/* Copy the AID to the params. */
	memcpy(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid, pAppId, 3); /* PRQA S 3200 */

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_GetApplicationIDs(void * pDataParams, uint8_t bOption, uint8_t ** ppAidBuff, uint8_t * pNumAIDs)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Validate the parameter. */
	if (((bOption & 0x0FU) != PH_EXCHANGE_DEFAULT) && ((bOption & 0x0FU) != PH_EXCHANGE_RXCHAINING))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_GET_APPLN_IDS;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = (uint8_t) (((bOption & 0x0FU) == PH_EXCHANGE_DEFAULT) ? PHAL_MFDFEVX_CMD_GET_APPLN_IDS : PHAL_MFDFEVX_RESP_ADDITIONAL_FRAME);

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	wStatus = phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode);
	if((wStatus == PH_ERR_SUCCESS) || ((wStatus & PH_ERR_MASK) == PH_ERR_SUCCESS_CHAINING))
	{
		/* Copy the data to the parameter */
		*ppAidBuff = pResponse;
		*pNumAIDs = (uint8_t) (wRespLen / 3);	
	}

	return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_GetDFNames(void * pDataParams, uint8_t bOption, uint8_t * pDFBuffer, uint8_t * bSize)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Validate the parameter. */
	if (((bOption & 0x0FU) != PH_EXCHANGE_DEFAULT) && ((bOption & 0x0FU) != PH_EXCHANGE_RXCHAINING))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_GET_DF_NAMES;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = (uint8_t) (((bOption & 0x0FU) == PH_EXCHANGE_DEFAULT) ? PHAL_MFDFEVX_CMD_GET_DF_NAMES : PHAL_MFDFEVX_RESP_ADDITIONAL_FRAME);

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	wStatus = phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode);
	if((wStatus == PH_ERR_SUCCESS) || ((wStatus & PH_ERR_MASK) == PH_ERR_SUCCESS_CHAINING))
	{
		/* Copy the data to the parameter */
		memcpy(pDFBuffer, pResponse, wRespLen);	/* PRQA S 3200 */
		*bSize = (uint8_t) wRespLen;
	}

	return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_GetDelegatedInfo(void * pDataParams, uint8_t * pDAMSlot, uint8_t * pDamSlotVer, uint8_t * pQuotaLimit, uint8_t * pFreeBlocks, uint8_t * pAid)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_GET_DELEGATED_INFO;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_GET_DELEGATED_INFO;

	/* Add DAM Slot number. */
	memcpy(&pAppData[wAppDataLen], pDAMSlot, 2);  /* PRQA S 3200 */
	wAppDataLen += 2;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	/* Copy the data to the parameter */
    memcpy(pDamSlotVer, &pResponse[0], 1); /* PRQA S 3200 */
    memcpy(pQuotaLimit, &pResponse[1], 2); /* PRQA S 3200 */
	memcpy(pFreeBlocks, &pResponse[3], 2); /* PRQA S 3200 */
    memcpy(pAid, &pResponse[5], 3); /* PRQA S 3200 */

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}




/* MIFARE DESFire EVx File mamangement commands. --------------------------------------------------------------------------------------- */
phStatus_t phalMfdfEVx_Sam_X_CreateStdDataFile(void * pDataParams, uint8_t bOption, uint8_t bFileNo, uint8_t * pISOFileId, uint8_t bFileOption, uint8_t * pAccessRights,
    uint8_t * pFileSize)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Validate the parameters. */
	if (((bFileNo & 0x7f) > 0x1f) || (bOption > 0x01))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

   if (((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_PLAIN >> 4U)) &&
        ((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_ENC >> 4U)) &&
        ((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_MACD >> 4U)))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_CREATE_STD_DATAFILE;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_CREATE_STD_DATAFILE;
	pAppData[wAppDataLen++] = bFileNo;
	
	/* Append ISOFileID is available. */
    if (bOption == 0x01)
    {
		memcpy(&pAppData[wAppDataLen], pISOFileId, 2); /* PRQA S 3200 */
		wAppDataLen += 2;
    }

    /* Append communication settings */
	pAppData[wAppDataLen++] = bFileOption;

    /* Append access rights. */
	memcpy(&pAppData[wAppDataLen], pAccessRights, 2); /* PRQA S 3200 */
	wAppDataLen += 2;

    /* Append FileSize. */
    memcpy(&pAppData[wAppDataLen], pFileSize, 3); /* PRQA S 3200 */
    wAppDataLen += 3;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_CreateBackupDataFile(void * pDataParams, uint8_t bOption, uint8_t bFileNo, uint8_t * pISOFileId, uint8_t bFileOption, uint8_t *pAccessRights,
	uint8_t * pFileSize)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Validate the parameters. */
	if (((bFileNo & 0x7f) > 0x1f) || (bOption > 0x01))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    if (((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_PLAIN >> 4U)) &&
        ((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_ENC >> 4U)) &&
        ((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_MACD >> 4U)))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_CREATE_BKUP_DATAFILE;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_CREATE_BKUP_DATAFILE;
	pAppData[wAppDataLen++] = bFileNo;
	
	/* Append ISOFileID is available. */
    if (bOption == 0x01)
    {
        memcpy(&pAppData[wAppDataLen], pISOFileId, 2); /* PRQA S 3200 */
		wAppDataLen += 2;
    }

    /* Append communication settings */
	pAppData[wAppDataLen++] = bFileOption;

    /* Append access rights. */
	memcpy(&pAppData[wAppDataLen], pAccessRights, 2); /* PRQA S 3200 */
	wAppDataLen += 2;

    /* Append FileSize. */
    memcpy(&pAppData[wAppDataLen], pFileSize, 3); /* PRQA S 3200 */
    wAppDataLen += 3;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_CreateValueFile(void * pDataParams, uint8_t bFileNo, uint8_t bFileOption, uint8_t * pAccessRights, uint8_t * pLowerLmit, uint8_t * pUpperLmit,
	uint8_t * pValue, uint8_t bLimitedCredit)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Validate the parameters. */
	if ((bFileNo & 0x7f) > 0x1f)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    if (((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_PLAIN >> 4U)) &&
        ((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_ENC >> 4U)) &&
        ((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_MACD >> 4U)))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_CREATE_VALUE_FILE;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_CREATE_VALUE_FILE;
	pAppData[wAppDataLen++] = bFileNo;

    /* Append communication settings */
	pAppData[wAppDataLen++] = bFileOption;

    /* Append access rights. */
	memcpy(&pAppData[wAppDataLen], pAccessRights, 2); /* PRQA S 3200 */
	wAppDataLen += 2;

    /* Append lower limit. */
    memcpy(&pAppData[wAppDataLen], pLowerLmit, 4); /* PRQA S 3200 */
    wAppDataLen += 4;

    /* Append upper limit. */
    memcpy(&pAppData[wAppDataLen], pUpperLmit, 4); /* PRQA S 3200 */
    wAppDataLen += 4;

    /* Append value. */
    memcpy(&pAppData[wAppDataLen], pValue, 4); /* PRQA S 3200 */
    wAppDataLen += 4;

	/* Append LimitedCreditEnabled information */
	pAppData[wAppDataLen++] = bLimitedCredit;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_CreateLinearRecordFile(void * pDataParams, uint8_t bOption, uint8_t  bFileNo, uint8_t * pISOFileId, uint8_t bFileOption, uint8_t * pAccessRights,
	uint8_t * pRecordSize, uint8_t * pMaxNoOfRec)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Validate the parameters. */
	if (((bFileNo & 0x7f) > 0x1f) || (bOption > 0x01))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    if (((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_PLAIN >> 4U)) &&
        ((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_ENC >> 4U)) &&
        ((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_MACD >> 4U)))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_CREATE_LINEAR_RECFILE;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_CREATE_LINEAR_RECFILE;
	pAppData[wAppDataLen++] = bFileNo;
	
	/* Append ISOFileID is available. */
    if (bOption == 0x01)
    {
        memcpy(&pAppData[wAppDataLen], pISOFileId, 2); /* PRQA S 3200 */
		wAppDataLen += 2;
    }

    /* Append communication settings */
	pAppData[wAppDataLen++] = bFileOption;

    /* Append access rights. */
	memcpy(&pAppData[wAppDataLen], pAccessRights, 2); /* PRQA S 3200 */
	wAppDataLen += 2;

    /* Append record size. */
	memcpy(&pAppData[wAppDataLen], pRecordSize, 3); /* PRQA S 3200 */
    wAppDataLen += 3;

    /* Append maximum number of records. */
	memcpy(&pAppData[wAppDataLen], pMaxNoOfRec, 3); /* PRQA S 3200 */
    wAppDataLen += 3;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_CreateCyclicRecordFile(void * pDataParams, uint8_t bOption, uint8_t  bFileNo, uint8_t * pISOFileId, uint8_t bFileOption, uint8_t * pAccessRights,
	uint8_t * pRecordSize, uint8_t * pMaxNoOfRec)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Validate the parameters. */
	if (((bFileNo & 0x7f) > 0x1f) || (bOption > 0x01))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    if (((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_PLAIN >> 4U)) &&
        ((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_ENC >> 4U)) &&
        ((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_MACD >> 4U)))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_CREATE_CYCLIC_RECFILE;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_CREATE_CYCLIC_RECFILE;
	pAppData[wAppDataLen++] = bFileNo;
	
	/* Append ISOFileID is available. */
    if (bOption == 0x01)
    {
        memcpy(&pAppData[wAppDataLen], pISOFileId, 2); /* PRQA S 3200 */
		wAppDataLen += 2;
    }

    /* Append communication settings */
	pAppData[wAppDataLen++] = bFileOption;

    /* Append access rights. */
	memcpy(&pAppData[wAppDataLen], pAccessRights, 2); /* PRQA S 3200 */
	wAppDataLen += 2;

    /* Append record size. */
	memcpy(&pAppData[wAppDataLen], pRecordSize, 3); /* PRQA S 3200 */
    wAppDataLen += 3;

    /* Append maximum number of records. */
	memcpy(&pAppData[wAppDataLen], pMaxNoOfRec, 3); /* PRQA S 3200 */
    wAppDataLen += 3;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_CreateTransactionMacFile(void * pDataParams, uint8_t bFileNo, uint8_t bFileOption, uint8_t * pAccessRights, uint16_t wKeyNo, uint8_t bKeyVer, 
	uint8_t bKeyType, uint8_t * pKey, uint8_t * pDivInput, uint8_t bDivInputLen)
{
	phStatus_t	PH_MEMLOC_REM wStatus = 0;
	uint8_t     PH_MEMLOC_REM bISOMode = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* VAlidate the parameters */
	if ((bFileNo > 0x1f) || (bKeyType != PHAL_MFDFEVX_KEY_TYPE_AES128))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

    if (((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_PLAIN >> 4U)) &&
        ((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_ENC >> 4U)) &&
        ((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_MACD >> 4U)))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_CREATE_TRANSTN_MACFILE;
	
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_NOT_AUTHENTICATED)
	{
		/* Frame the command information. */
		pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_CREATE_TRANSTN_MACFILE;
		pAppData[wAppDataLen++] = bFileNo;
		pAppData[wAppDataLen++] = bFileOption;

		/* Append access rights. */
		memcpy(&pAppData[wAppDataLen], pAccessRights, 2); /* PRQA S 3200 */
		wAppDataLen += 2;

		/* Append TMKeyOption. */
		pAppData[wAppDataLen++] = bKeyType;

		/* Append TMKey. */
		memcpy(&pAppData[wAppDataLen], pKey, 16); /* PRQA S 3200 */
		wAppDataLen += 16;

		/* Append TMKeyVer. */
		pAppData[wAppDataLen++] = bKeyVer;

		/* Wrap the command if required. */
		PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
			pDataParams,
			PH_ON,
			PH_OFF,
			0,
			PH_ON,
			0,
			pAppData,
			&wAppDataLen));

		/* Exchange the information to Sam. */
		wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
			PH_EXCHANGE_DEFAULT,
			PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN,
			pAppData,
			(uint8_t) wAppDataLen,
			&pResponse,
			&wRespLen,
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
			&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);
	}
	else
	{
		/* Set Native or ISO7816 PICC command format. */
		bISOMode = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode? PHHAL_HW_CMD_SAMAV3_ISO_MODE_ISO7816 : 
			PHHAL_HW_CMD_SAMAV3_ISO_MODE_NATIVE);

		wStatus = phhalHw_SamAV3_Cmd_DESFire_CreateTMFilePICC(
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
			(uint8_t) (bDivInputLen ? PHHAL_HW_CMD_SAMAV3_KEY_DIVERSIFICATION_ON : PHHAL_HW_CMD_SAMAV3_KEY_DIVERSIFICATION_OFF),
			bISOMode,
			(uint8_t) wKeyNo,
			bKeyVer,
			bFileNo,
			(uint8_t) (bFileOption >> 4),
			pAccessRights,
			bKeyType,
			pDivInput,
			bDivInputLen,
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode);
	}

	/* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_DeleteFile(void * pDataParams, uint8_t bFileNo)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Validate the parameters. */
	if ((bFileNo & 0x7f) > 0x1f)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_DELETE_FILE;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_DELETE_FILE;
	pAppData[wAppDataLen++] = bFileNo;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_GetFileIDs(void * pDataParams, uint8_t * pFid, uint8_t * bNumFIDs)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_GET_FILE_IDS;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_GET_FILE_IDS;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	wStatus = phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode);
	if((wStatus == PH_ERR_SUCCESS) || ((wStatus & PH_ERR_MASK) == PH_ERR_SUCCESS_CHAINING))
	{
		/* Copy the data to the parameter */
		memcpy(pFid, pResponse, wRespLen); /* PRQA S 3200 */
		*bNumFIDs = (uint8_t) wRespLen;
	}

	return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_GetISOFileIDs(void * pDataParams, uint8_t * pFidBuffer, uint8_t * bNumFIDs)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;
	uint8_t		PH_MEMLOC_REM bFinished = 0;

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_GET_ISO_FILE_IDS;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_GET_ISO_FILE_IDS;

	/* Set the number of FileID variable. */
	*bNumFIDs = 0;

	do
	{
		/* Wrap the command if required. */
		PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
			pDataParams,
			PH_ON,
			PH_OFF,
			0,
			PH_ON,
			0,
			pAppData,
			&wAppDataLen));

		/* Exchange the information to Sam. */
		wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
			PH_EXCHANGE_DEFAULT,
			bCrypto,
			pAppData,
			(uint8_t) wAppDataLen,
			&pResponse,
			&wRespLen,
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
			&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

		/* Evaluate the response. */
		wStatus = phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode);

		if(((wStatus & PH_ERR_MASK) != PH_ERR_SUCCESS_CHAINING) && ((wStatus & PH_ERR_MASK) != PH_ERR_SUCCESS))
		{
			PH_CHECK_SUCCESS(wStatus);
		}
		else
		{
			/* Update Command frame. */
			wAppDataLen = 0;
			pAppData[wAppDataLen++] = 0xAF;

			/* Copy the data to the parameter */
			memcpy(&pFidBuffer[*bNumFIDs * 2], pResponse, wRespLen);	/* PRQA S 3200 */
			*bNumFIDs += (uint8_t) (wRespLen / 2);

			/* Update Finish flag. */
			if((wStatus & PH_ERR_MASK) == PH_ERR_SUCCESS)
			{
				bFinished = 1;
			}
		}
	}while(!bFinished);

	return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_GetFileSettings(void * pDataParams, uint8_t bFileNo, uint8_t * pFSBuffer, uint8_t * pBufferLen)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Validate the parameters. */
	if ((bFileNo & 0x7f) > 0x1f)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_GET_FILE_SETTINGS;

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_GET_FILE_SETTINGS;
	pAppData[wAppDataLen++] = bFileNo;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	/* Copy the data to the parameter */
	memcpy(pFSBuffer, pResponse, wRespLen);	/* PRQA S 3200 */
	*pBufferLen = (uint8_t) wRespLen;

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_GetFileCounters(void * pDataParams, uint8_t bOption, uint8_t bFileNo, uint8_t * pResponse, uint8_t * pRespLen)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponseTmp = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;
	uint8_t		PH_MEMLOC_REM bLenPresent = 0;

	/* Validate the parameters */
	if ((bOption != PHAL_MFDFEVX_COMMUNICATION_PLAIN) &&
        (bOption != PHAL_MFDFEVX_COMMUNICATION_ENC))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_GET_FILE_COUNTERS;

	/* Append expected length to the command frame. */
	if (bOption == PHAL_MFDFEVX_COMMUNICATION_ENC)
	{
		pAppData[wAppDataLen++] = 5;
		pAppData[wAppDataLen++] = 0;
		pAppData[wAppDataLen++] = 0;

		/* Set Length Presence flag. */
		bLenPresent = PH_ON;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_GET_FILE_COUNTERS;
	pAppData[wAppDataLen++] = bFileNo;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		bLenPresent,
		3,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bOption,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponseTmp,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	/* Copy the data to the parameter */
	memcpy(pResponse, pResponseTmp, wRespLen);	/* PRQA S 3200 */
	*pRespLen = (uint8_t) wRespLen;

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_ChangeFileSettings(void * pDataParams, uint8_t bOption, uint8_t bFileNo, uint8_t bFileOption, uint8_t * pAccessRights, uint8_t bAddInfoLen,
	uint8_t * pAddInfo)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
	uint8_t		PH_MEMLOC_REM bAddARsLen = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t		PH_MEMLOC_REM bLenPresent = 0;
	
	/* Validate the parameters */
	if ((bFileNo & 0x3f) > 0x1f)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    if (((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_PLAIN >> 4U)) &&
        ((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_ENC >> 4U)) &&
        ((bFileOption & 0x03U) != (PHAL_MFDFEVX_COMMUNICATION_MACD >> 4U)))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */
		
	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_FULL;
	if((bOption & 0x30U) != PHAL_MFDFEVX_COMMUNICATION_ENC)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	}
	
	/* Set the Command Offset. */
	if((bOption & 0x30U) == PHAL_MFDFEVX_COMMUNICATION_ENC) 
	{
		if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode != PHAL_MFDFEVX_AUTHENTICATEEV2)
			bCrypto |= (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? 6 : 2);
		else
		{
			/* Start of data. */
			pAppData[wAppDataLen++] = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? 6 : 2);

			/* Set Extended Offset in Crypto mode. */
			bCrypto |= PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_EXTENDED_OFFSET;

			/* Set Length Presence flag. */
			bLenPresent = PH_ON;
		}
	}

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_CHANGE_FILE_SETTINGS;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_CHANGE_FILE_SETTINGS;
	pAppData[wAppDataLen++] = bFileNo;
	pAppData[wAppDataLen++] = bFileOption;
    pAppData[wAppDataLen++] = pAccessRights[0];
    pAppData[wAppDataLen++] = pAccessRights[1];

	if (bOption & PHAL_MFDFEVX_EXCHANGE_ADD_INFO_BUFFER_COMPLETE)
	{
		/* SDM buffer in command buffer if Bit6 of File Option is SET.  */
        memcpy(&pAppData[wAppDataLen], pAddInfo, bAddInfoLen);
		wAppDataLen += bAddInfoLen;
	}
	else
	{
		if (bFileOption & PHAL_MFDFEVX_FILE_OPTION_ADDITIONAL_AR_PRESENT)
		{
			/* Compute the Additional ACCESS Rights length. */
			bAddARsLen = (uint8_t) ((bFileOption & PHAL_MFDFEVX_FILE_OPTION_TMCLIMIT_PRESENT) ? (bAddInfoLen - 4) : bAddInfoLen);

			pAppData[wAppDataLen++] = bAddARsLen;
			memcpy(&pAppData[wAppDataLen], pAddInfo, (bAddARsLen * 2)); /* PRQA S 3200 */
			wAppDataLen += (bAddARsLen * 2);
		}

		/* TMCLimit buffer in command buffer if Bit5 of File Option is SET. */
		if (bFileOption & PHAL_MFDFEVX_FILE_OPTION_TMCLIMIT_PRESENT)
		{
			memcpy(&pAppData[wAppDataLen], &pAddInfo[bAddARsLen], 4); /* PRQA S 3200 */
			wAppDataLen += 4;
		}
	}

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		bLenPresent,
		1,
		PH_OFF,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}




/* MIFARE DESFire EVx Data mamangement commands. --------------------------------------------------------------------------------------- */
phStatus_t phalMfdfEVx_Sam_X_ReadData(void * pDataParams, uint8_t bOption, uint8_t bIns, uint8_t bFileNo, uint8_t * pOffset, uint8_t * pLength, uint8_t ** ppResponse, 
	uint16_t * pRespLen)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
	phStatus_t	PH_MEMLOC_REM wStatus1 = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
	uint16_t	PH_MEMLOC_REM wOption = 0;
    uint8_t     PH_MEMLOC_REM bLengthPresent = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t    PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
    uint8_t     PH_MEMLOC_REM aPiccRetCode[2];
	uint8_t		PH_MEMLOC_REM bPiccRetCodeLen = 0;

	static uint32_t	PH_MEMLOC_REM dwLength = 0;
	uint8_t		PH_MEMLOC_REM bTMIOption = 0;
    uint32_t    PH_MEMLOC_REM dwTMIStatus = 0;

	/* Validate the parameter. */
	if (((bFileNo & 0x7f) > 0x1f) || (bIns > 0x01))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    if (((bOption & 0xF0) != PHAL_MFDFEVX_COMMUNICATION_PLAIN) &&
        ((bOption & 0xF0) != PHAL_MFDFEVX_COMMUNICATION_ENC) &&
        ((bOption & 0xF0) != PHAL_MFDFEVX_COMMUNICATION_MACD))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	if (((bOption & 0x0FU) != PH_EXCHANGE_DEFAULT) && ((bOption & 0x0FU) != PH_EXCHANGE_RXCHAINING))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Frame the Crypto information. */
	bCrypto = (uint8_t) (bOption & 0xF0);

	/* Frame Option parameter. */
	wOption = (uint16_t) (bOption & 0x0FU) ;
	wOption |= (uint16_t) (bIns ? PHHAL_HW_CMD_SAMAV3_ISO_CHAINING : 0);

	/* Compute the length. */
	dwLength = pLength[2];
	dwLength = dwLength << 8 | pLength[1];
	dwLength = dwLength << 8 | pLength[0];

	/* Frame the command information based on the option. */
    if ((bOption & 0x0FU) == PH_EXCHANGE_RXCHAINING)
    {
		/* Frame additional frame code only for Native chaining. */
		if(!bIns)
		{
			pAppData[wAppDataLen++] = PHAL_MFDFEVX_RESP_ADDITIONAL_FRAME;
		}
    }
    else
    {
		/* Frame Presence of length information in the command frame. 
		 * The first three bytes specifies number of bytes to be received from PICC.
		 */
		bLengthPresent = (uint8_t) (((bOption & 0xF0) == PHAL_MFDFEVX_COMMUNICATION_ENC) ? PH_ON : PH_OFF);

		/* Add Read Length if communication mode is Encrypted. */
		if(bLengthPresent)
		{
			memcpy(&pAppData[wAppDataLen], pLength, 3); /* PRQA S 3200 */
			wAppDataLen += 3;
		}

        pAppData[wAppDataLen++] = (uint8_t) ((bIns) ? PHAL_MFDFEVX_CMD_READ_DATA_ISO : PHAL_MFDFEVX_CMD_READ_DATA);
        pAppData[wAppDataLen++] = bFileNo;

        memcpy(&pAppData[wAppDataLen], pOffset, 3); /* PRQA S 3200 */
        wAppDataLen += 3;

        memcpy(&pAppData[wAppDataLen], pLength, 3); /* PRQA S 3200 */
        wAppDataLen += 3;

		/* Get the TMI Status. */
		PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_GetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams, PH_TMIUTILS_TMI_STATUS,
			&dwTMIStatus));

		/* Check TMI Collection Status */
		if (dwTMIStatus)
		{
			/* Frame the Option. */
			bTMIOption = (uint8_t)(dwLength ? PH_TMIUTILS_ZEROPAD_CMDBUFF : (PH_TMIUTILS_READ_INS | PH_TMIUTILS_ZEROPAD_CMDBUFF));

			/* Buffer the Command information to TMI buffer. */
			PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
				bTMIOption, pAppData, wAppDataLen, NULL, 0, PHAL_MFDFEVX_BLOCK_SIZE));
		}
    }

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		bLengthPresent,
		3,
		PH_ON,
		((pLength[0] | (pLength[1] << 8) | (pLength[2] << 8)) + 7),
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		wOption,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		ppResponse,
		pRespLen,
		aPiccRetCode,
		&bPiccRetCodeLen);

    /* Evaluate the response. */
	wStatus = phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, aPiccRetCode);

	/* Get the TMI Status. */
	PH_CHECK_SUCCESS_FCT(wStatus1, phTMIUtils_GetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams, PH_TMIUTILS_TMI_STATUS,
		&dwTMIStatus));

	/* Check TMI Collection Status */
	if (dwTMIStatus && ((wStatus == PH_ERR_SUCCESS) || ((wStatus & PH_ERR_MASK) == PH_ERR_SUCCESS_CHAINING)))
	{
		/* Frame the Option. */
		bTMIOption = (uint8_t) (dwLength ? 0 : PH_TMIUTILS_READ_INS);
		bTMIOption = (uint8_t) ((wStatus == PH_ERR_SUCCESS) ? (bTMIOption | PH_TMIUTILS_ZEROPAD_DATABUFF) : bTMIOption);

		/* Collect the data received. */
		PH_CHECK_SUCCESS_FCT(wStatus1, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
			bTMIOption, NULL, 0, *ppResponse, *pRespLen, PHAL_MFDFEVX_BLOCK_SIZE));

		/* Reset the TMI buffer Offset. */
		if (!dwLength && (wStatus == PH_ERR_SUCCESS))
		{
			/* Reset wOffsetInTMI */
			PH_CHECK_SUCCESS_FCT(wStatus1, phTMIUtils_SetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
				PH_TMIUTILS_TMI_OFFSET_LENGTH, 0));
		}
	}

    return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_WriteData(void * pDataParams, uint8_t bOption, uint8_t bIns, uint8_t bFileNo, uint8_t * pOffset, uint8_t * pData, uint8_t * pDataLen)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
	uint16_t	PH_MEMLOC_REM wBufferOption = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
	uint8_t		PH_MEMLOC_REM bLenPresent = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint16_t    PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataOffset = 0;
    uint8_t     PH_MEMLOC_REM aPiccRetCode[2];
	uint8_t		PH_MEMLOC_REM bPiccRetCodeLen = 0;
	uint8_t		PH_MEMLOC_REM bIsFirstFrame = PH_ON;
	uint8_t		PH_MEMLOC_REM bDataLen = 0;
	uint8_t		PH_MEMLOC_REM bOffset = 0;
	uint32_t	PH_MEMLOC_REM dwTotLen = 0;
	uint32_t	PH_MEMLOC_REM dwRemLen = 0;
	uint8_t		PH_MEMLOC_REM bExchangeComplete = 0;
    uint32_t	PH_MEMLOC_REM dwTMIStatus = 0;
	
	/* Validate the parameters */
	if (((bFileNo & 0x7f) > 0x1f) || (bIns > 0x01))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}
	if ((bOption != PHAL_MFDFEVX_COMMUNICATION_PLAIN) &&
		(bOption != PHAL_MFDFEVX_COMMUNICATION_ENC) &&
		(bOption != PHAL_MFDFEVX_COMMUNICATION_MACD))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Compute the maximum length. */
	dwTotLen = (uint32_t) (pDataLen[0] | (pDataLen[1] << 8) | (pDataLen[2] << 16));

	/* Update Offset information in case FULL Mode. */
	if((bOption == PHAL_MFDFEVX_COMMUNICATION_ENC) &&
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
	{
		pAppData[wAppDataLen++] = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? 12 : 8);
		pAppData[0] = (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode && (bIns && ( dwTotLen > 0xFE))) ? 
			(pAppData[0] + 2) : pAppData[0]);

		/* Set Length Presence flag. */
		bLenPresent = PH_ON;

		/* Set the Application data offset. This should not go for TMI collection. */
		wAppDataOffset = 1;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = (uint8_t) (bIns ? PHAL_MFDFEVX_CMD_WRITE_DATA_ISO : PHAL_MFDFEVX_CMD_WRITE_DATA);
	pAppData[wAppDataLen++] = bFileNo;

	memcpy(&pAppData[wAppDataLen], pOffset, 3);
	wAppDataLen += 3;

	memcpy(&pAppData[wAppDataLen], pDataLen, 3);
	wAppDataLen += 3;
	
	/* Get the TMI Status. */
	PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_GetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams, PH_TMIUTILS_TMI_STATUS,
		&dwTMIStatus));

	/* Check TMI Collection Status */
	if (dwTMIStatus)
	{
		/* Buffer the Command and Data information to TMI buffer. */
		PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
			(PH_TMIUTILS_ZEROPAD_CMDBUFF | PH_TMIUTILS_ZEROPAD_DATABUFF), &pAppData[wAppDataOffset], (uint16_t) (wAppDataLen - wAppDataOffset), 
			pData, dwTotLen, PHAL_MFDFEVX_BLOCK_SIZE));
	}
	
	/* Set the buffering flag. */
	wBufferOption = (uint16_t) (PH_EXCHANGE_DEFAULT | PH_EXCHANGE_TXCHAINING);

	/* Set the lengths. */
	dwRemLen = dwTotLen;

	do
	{
		/* Compute the maximum data to be exchanged.  */
		if(bIsFirstFrame)
		{
			bDataLen = (uint8_t) (PHAL_MFDFEVX_MAX_WRITE_LEN - 8) /* The command header information is available. */;
			bDataLen = (uint8_t) ((bOption == PHAL_MFDFEVX_COMMUNICATION_ENC) ? (bDataLen - 4) : bDataLen);

			if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode)
			{
				bDataLen = (uint8_t) ((bOption == PHAL_MFDFEVX_COMMUNICATION_ENC) ? (bDataLen - 16) : (bDataLen - 20));
			}
		}
		else
		{
			if(bIns)
			{
				bDataLen = (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? (PHAL_MFDFEVX_MAX_WRITE_LEN - 5) : PHAL_MFDFEVX_MAX_WRITE_LEN));
			}
			else
			{
				bDataLen = (uint8_t) (PHAL_MFDFEVX_MAX_WRITE_LEN - 1);
				if(bOption == PHAL_MFDFEVX_COMMUNICATION_ENC)
				{
					bDataLen = (uint8_t) (((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEAES) ||
										   (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)) ?
										   (bDataLen - 11) : (bDataLen - 3));
				}

				if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode)
				{
					bDataLen = (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2) ? 16 : 32);
				}
			}
		}

		/* Set the completion flag. */
		if(dwRemLen <= bDataLen)
		{
			bDataLen = (uint8_t) dwRemLen;
			wBufferOption = PH_EXCHANGE_DEFAULT;
			bExchangeComplete = PH_ON;
		}

		/* Copy the data to the buffer. */
		memcpy(&pAppData[wAppDataLen], &pData[bOffset], bDataLen);
		wAppDataLen += bDataLen;

		/* Wrap the command if required. */
		if(bIsFirstFrame || !bIns)
		{
			PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
				pDataParams,
				PH_ON,
				bLenPresent,
				1,
				PH_OFF,
				(dwTotLen + 7),
				pAppData,
				&wAppDataLen));
		}

		/* Frame the Crypto information. */
		bCrypto = (uint8_t) (bOption | ((bIns && ( dwTotLen > PHAL_MFDFEVX_MAX_WRITE_LEN))? PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_ISO_CHAINING : 
			PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_DESFIRE_CHAINING));

		/* Set the Offset information for MAC and FULL mode. */
		if(bOption != PHAL_MFDFEVX_COMMUNICATION_PLAIN)
		{
			bCrypto |= (uint8_t) (bIsFirstFrame ? 8 : bIns ? 0 : 1);
			bCrypto |= (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode) ? (bCrypto + 4) : bCrypto);
			bCrypto = (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode && (bIns && ( dwTotLen > 0xFE))) ? 
				(bCrypto + 2) : bCrypto);

			/* Reset the Crypto to zero . */
			if(bIns && !bIsFirstFrame)
			{
				bCrypto = 0;
			}
		}

		/* Set ExtendedOffset for Full mode and ISO Chaining. */
		if((bOption == PHAL_MFDFEVX_COMMUNICATION_ENC) && bIsFirstFrame &&
			(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
		{
			/* Mask out the previously set offset. */
			bCrypto = (uint8_t) (bCrypto & 0xF0);

			/* Set the Extended Offset bit. */
			bCrypto |= PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_EXTENDED_OFFSET;
		}

		/* Clear the first frame and Length Presence flag. */
		bIsFirstFrame = PH_OFF;
		bLenPresent = PH_OFF;

		/* Enchange the information to SAM. */
		wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
			wBufferOption,
			bCrypto,
			pAppData,
			(uint8_t) wAppDataLen,
			aPiccRetCode,
			&bPiccRetCodeLen);

		/* Evaluate the response. */
		wStatus = phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, aPiccRetCode);

		/* Return the status if not SUCCESS or SUCCESS_CHAINING. */
		if((wStatus != PH_ERR_SUCCESS) && ((wStatus & PH_ERR_MASK) != PH_ERR_SUCCESS_CHAINING))
		{
			return wStatus;
		}

		/* Update length. */
		bOffset += bDataLen;
		dwRemLen = (uint32_t) (dwRemLen - bDataLen);
		
		/* Set the Chaining satus. */
		wAppDataLen = 0;

		if(!bIns)
		{
			pAppData[wAppDataLen++] = PHAL_MFDFEVX_RESP_ADDITIONAL_FRAME;
		}

	}while(!bExchangeComplete);

    return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_GetValue(void * pDataParams, uint8_t bCommOption, uint8_t bFileNo, uint8_t * pValue)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t     PH_MEMLOC_REM bLengthPresent = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint16_t    PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataOffset = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;
    uint8_t     PH_MEMLOC_REM aPiccRetCode[2];
	uint8_t		PH_MEMLOC_REM bPiccRetCodeLen = 0;
    uint32_t	PH_MEMLOC_REM dwTMIStatus = 0;

	/* Validate the parameters. */
	if ((bFileNo & 0x7f) > 0x1f)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	if ((bCommOption != PHAL_MFDFEVX_COMMUNICATION_PLAIN) &&
        (bCommOption != PHAL_MFDFEVX_COMMUNICATION_ENC) &&
        (bCommOption != PHAL_MFDFEVX_COMMUNICATION_MACD))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Frame the Crypto information. */
	bCrypto = bCommOption;

	/* Append expected length to the command frame. */
	if(bCommOption == PHAL_MFDFEVX_COMMUNICATION_ENC)
	{
		pAppData[wAppDataLen++] = 4;
		pAppData[wAppDataLen++] = 0;
		pAppData[wAppDataLen++] = 0;

		bLengthPresent = PH_ON;

		/* Set the Application data offset. This should not go for TMI collection. */
		wAppDataOffset = 3;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_GET_VALUE;
	pAppData[wAppDataLen++] = bFileNo;

	/* Get the TMI Status. */
	PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_GetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams, PH_TMIUTILS_TMI_STATUS,
		&dwTMIStatus));

	/* Check TMI Collection Status */
	if (dwTMIStatus)
	{
		/* Buffer the Command and Data information to TMI buffer. */
		PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
			PH_TMIUTILS_NO_PADDING, &pAppData[wAppDataOffset], (uint16_t) (wAppDataLen - wAppDataOffset), NULL, 0, 
			PHAL_MFDFEVX_BLOCK_SIZE));
    }

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		bLengthPresent,
		3,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		aPiccRetCode,
		&bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, aPiccRetCode));

	 /* Copy the value. */
    memcpy(pValue, pResponse, wRespLen); /* PRQA S 3200 */

	/* Check TMI Collection Status */
	if (dwTMIStatus)
	{
		/* Buffer the Command and Data information to TMI buffer. */
		PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
			PH_TMIUTILS_ZEROPAD_DATABUFF, NULL, 0, pValue, wRespLen, PHAL_MFDFEVX_BLOCK_SIZE));
    }

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_Credit(void * pDataParams, uint8_t bCommOption, uint8_t bFileNo, uint8_t * pValue)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint16_t    PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataOffset = 0;
    uint8_t     PH_MEMLOC_REM aPiccRetCode[2];
	uint8_t		PH_MEMLOC_REM bPiccRetCodeLen = 0;
	uint8_t		PH_MEMLOC_REM bLenPresent = 0;
	uint32_t	PH_MEMLOC_REM dwTMIStatus = 0;
	
	/* Validate the parameters */
	if ((bFileNo & 0x3f) > 0x1f)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    if ((bCommOption != PHAL_MFDFEVX_COMMUNICATION_PLAIN) &&
        (bCommOption != PHAL_MFDFEVX_COMMUNICATION_ENC) &&
        (bCommOption != PHAL_MFDFEVX_COMMUNICATION_MACD))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Update Offset information in case FULL Mode. */
	if((bCommOption == PHAL_MFDFEVX_COMMUNICATION_ENC) &&
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
	{
		pAppData[wAppDataLen++] = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? 6 : 2);

		/* Set Length Presence flag. */
		bLenPresent = PH_ON;

		/* Set the Application data offset. This should not go for TMI collection. */
		wAppDataOffset = 1;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_CREDIT;
	pAppData[wAppDataLen++] = bFileNo;

   /* Get the TMI Status. */
	PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_GetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams, PH_TMIUTILS_TMI_STATUS,
		&dwTMIStatus));

	/* Check TMI Collection Status */
	if (dwTMIStatus)
	{
		/* Buffer the Command and Data information to TMI buffer. */
		PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
			PH_TMIUTILS_ZEROPAD_DATABUFF, &pAppData[wAppDataOffset], (uint16_t) (wAppDataLen - wAppDataOffset), pValue, 4,
			PHAL_MFDFEVX_BLOCK_SIZE));
    }

    /* Append data. */
	memcpy(&pAppData[wAppDataLen], pValue, 4); /* PRQA S 3200 */
	wAppDataLen += 4;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		bLenPresent,
		1,
		PH_OFF,
		0,
		pAppData,
		&wAppDataLen));

	/* Frame the Crypto information. */
	bCrypto = bCommOption;

	/* Set ExtendedOffset for Full mode and ISO Chaining. */
	if((bCommOption == PHAL_MFDFEVX_COMMUNICATION_ENC) && 
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
	{
		/* Set the Extended Offset bit. */
		bCrypto |= PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_EXTENDED_OFFSET;
	}
	else
	{
		bCrypto = (uint8_t) (bCrypto + (wAppDataLen - 4 /* Data Length */));
	}

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		aPiccRetCode,
		&bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_Debit(void * pDataParams, uint8_t bCommOption, uint8_t bFileNo, uint8_t * pValue)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint16_t    PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataOffset = 0;
    uint8_t     PH_MEMLOC_REM aPiccRetCode[2];
	uint8_t		PH_MEMLOC_REM bPiccRetCodeLen = 0;
	uint8_t		PH_MEMLOC_REM bLenPresent = 0;
	uint32_t	PH_MEMLOC_REM dwTMIStatus = 0;
	
	/* Validate the parameters */
	if ((bFileNo & 0x3f) > 0x1f)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    if (((bCommOption & 0x3f) != PHAL_MFDFEVX_COMMUNICATION_PLAIN) &&
        ((bCommOption & 0x3f) != PHAL_MFDFEVX_COMMUNICATION_ENC) &&
        ((bCommOption & 0x3f) != PHAL_MFDFEVX_COMMUNICATION_MACD))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Update Offset information in case FULL Mode. */
	if((bCommOption == PHAL_MFDFEVX_COMMUNICATION_ENC) &&
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
	{
		pAppData[wAppDataLen++] = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? 6 : 2);

		/* Set Length Presence flag. */
		bLenPresent = PH_ON;

		/* Set the Application data offset. This should not go for TMI collection. */
		wAppDataOffset = 1;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_DEBIT;
	pAppData[wAppDataLen++] = bFileNo;

   /* Get the TMI Status. */
	PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_GetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams, PH_TMIUTILS_TMI_STATUS,
		&dwTMIStatus));

	/* Check TMI Collection Status */
	if (dwTMIStatus)
	{
		/* Buffer the Command and Data information to TMI buffer. */
		PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
			PH_TMIUTILS_ZEROPAD_DATABUFF, &pAppData[wAppDataOffset], (uint16_t) (wAppDataLen - wAppDataOffset), pValue, 4, 
			PHAL_MFDFEVX_BLOCK_SIZE));
    }

    /* Append data. */
	memcpy(&pAppData[wAppDataLen], pValue, 4); /* PRQA S 3200 */
	wAppDataLen += 4;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		bLenPresent,
		1,
		PH_OFF,
		0,
		pAppData,
		&wAppDataLen));

	/* Frame the Crypto information. */
	bCrypto = bCommOption;

	/* Set ExtendedOffset for Full mode and ISO Chaining. */
	if((bCommOption == PHAL_MFDFEVX_COMMUNICATION_ENC) && 
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
	{
		/* Set the Extended Offset bit. */
		bCrypto |= PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_EXTENDED_OFFSET;
	}
	else
	{
		bCrypto = (uint8_t) (bCrypto + (wAppDataLen - 4 /* Data Length */));
	}

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		aPiccRetCode,
		&bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_LimitedCredit(void * pDataParams, uint8_t bCommOption, uint8_t bFileNo, uint8_t * pValue)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint16_t    PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataOffset = 0;
    uint8_t     PH_MEMLOC_REM aPiccRetCode[2];
	uint8_t		PH_MEMLOC_REM bPiccRetCodeLen = 0;
	uint8_t		PH_MEMLOC_REM bLenPresent = 0;
	uint32_t	PH_MEMLOC_REM dwTMIStatus = 0;
	
	/* Validate the parameters */
	if ((bFileNo & 0x3f) > 0x1f)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    if (((bCommOption & 0x3f) != PHAL_MFDFEVX_COMMUNICATION_PLAIN) &&
        ((bCommOption & 0x3f) != PHAL_MFDFEVX_COMMUNICATION_ENC) &&
        ((bCommOption & 0x3f) != PHAL_MFDFEVX_COMMUNICATION_MACD))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Update Offset information in case FULL Mode. */
	if((bCommOption == PHAL_MFDFEVX_COMMUNICATION_ENC) &&
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
	{
		pAppData[wAppDataLen++] = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? 6 : 2);

		/* Set Length Presence flag. */
		bLenPresent = PH_ON;

		/* Set the Application data offset. This should not go for TMI collection. */
		wAppDataOffset = 1;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_LIMITED_CREDIT;
	pAppData[wAppDataLen++] = bFileNo;

   /* Get the TMI Status. */
	PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_GetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams, PH_TMIUTILS_TMI_STATUS,
		&dwTMIStatus));

	/* Check TMI Collection Status */
	if (dwTMIStatus)
	{
		/* Buffer the Command and Data information to TMI buffer. */
		PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
			PH_TMIUTILS_ZEROPAD_DATABUFF, &pAppData[wAppDataOffset], (uint16_t) (wAppDataLen - wAppDataOffset), pValue, 4,
			PHAL_MFDFEVX_BLOCK_SIZE));
    }

    /* Append data. */
	memcpy(&pAppData[wAppDataLen], pValue, 4); /* PRQA S 3200 */
	wAppDataLen += 4;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		bLenPresent,
		1,
		PH_OFF,
		0,
		pAppData,
		&wAppDataLen));

	/* Frame the Crypto information. */
	bCrypto = bCommOption;

	/* Set ExtendedOffset for Full mode and ISO Chaining. */
	if((bCommOption == PHAL_MFDFEVX_COMMUNICATION_ENC) && 
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
	{
		/* Set the Extended Offset bit. */
		bCrypto |= PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_EXTENDED_OFFSET;
	}
	else
	{
		bCrypto = (uint8_t) (bCrypto + (wAppDataLen - 4 /* Data Length */));
	}

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		aPiccRetCode,
		&bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_ReadRecords(void * pDataParams, uint8_t bOption, uint8_t bIns, uint8_t bFileNo, uint8_t * pRecNo, uint8_t * pRecCount, uint8_t * pRecSize,
	uint8_t ** ppResponse, uint16_t * pRespLen)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
	phStatus_t	PH_MEMLOC_REM wStatus1 = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
	uint16_t	PH_MEMLOC_REM wOption = 0;
    uint8_t     PH_MEMLOC_REM bLengthPresent = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint16_t    PH_MEMLOC_REM wAppDataSize = 0;
    uint8_t     PH_MEMLOC_REM aPiccRetCode[2];
	uint8_t		PH_MEMLOC_REM bPiccRetCodeLen = 0;

	static uint32_t	PH_MEMLOC_REM dwLength = 0;
	uint32_t	PH_MEMLOC_REM dwNumRec = 0;
	uint32_t	PH_MEMLOC_REM dwRecLen = 0;
	uint8_t		PH_MEMLOC_REM bTMIOption = 0;
    uint32_t    PH_MEMLOC_REM dwTMIStatus = 0;

	/* Validate the parameter. */
	if (((bFileNo & 0x7f) > 0x1f) || (bIns > 0x01))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    if (((bOption & 0xF0) != PHAL_MFDFEVX_COMMUNICATION_PLAIN) &&
        ((bOption & 0xF0) != PHAL_MFDFEVX_COMMUNICATION_ENC) &&
        ((bOption & 0xF0) != PHAL_MFDFEVX_COMMUNICATION_MACD))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	if (((bOption & 0x0FU) != PH_EXCHANGE_DEFAULT) && ((bOption & 0x0FU) != PH_EXCHANGE_RXCHAINING))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Frame the Crypto information. */
	bCrypto = (uint8_t) (bOption & 0xF0);

	/* Frame Option parameter. */
	wOption = (uint16_t) (bOption & 0x0FU) ;
	wOption |= (uint16_t) (bIns ? PHHAL_HW_CMD_SAMAV3_ISO_CHAINING : 0);

	/* Compute the length. */
	dwLength = pRecSize[2];
	dwLength = dwLength << 8 | pRecSize[1];
	dwLength = dwLength << 8 | pRecSize[0];

	/* Frame the command information based on the option. */
    if ((bOption & 0x0FU) == PH_EXCHANGE_RXCHAINING)
    {
		/* Frame additional frame code only for Native chaining. */
		if(!bIns)
		{
			pAppData[wAppDataLen++] = PHAL_MFDFEVX_RESP_ADDITIONAL_FRAME;
		}
    }
    else
    {
		/* Frame Presence of length information in the command frame. 
		 * The first three bytes specifies number of bytes to be received from PICC.
		 */
		bLengthPresent = (uint8_t) (((bOption & 0xF0) == PHAL_MFDFEVX_COMMUNICATION_ENC) ? PH_ON : PH_OFF);

		/* Add Read Length if communication mode is Encrypted. */
		if(bLengthPresent)
		{
			memcpy(&pAppData[wAppDataLen], pRecSize, 3); /* PRQA S 3200 */
			wAppDataLen += 3;
		}

        pAppData[wAppDataLen++] = (uint8_t) ((bIns) ? PHAL_MFDFEVX_CMD_READ_RECORDS_ISO : PHAL_MFDFEVX_CMD_READ_RECORDS );
        pAppData[wAppDataLen++] = bFileNo;

		memcpy(&pAppData[wAppDataLen], pRecNo, 3); /* PRQA S 3200 */
        wAppDataLen += 3;

		memcpy(&pAppData[wAppDataLen], pRecCount, 3); /* PRQA S 3200 */
        wAppDataLen += 3;

		/* Get the TMI Status. */
		PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_GetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams, PH_TMIUTILS_TMI_STATUS,
			&dwTMIStatus));

		/* Check TMI Collection Status */
		if (dwTMIStatus)
		{
			/* Compute the number of records. */
			dwNumRec = pRecCount[2];
			dwNumRec = dwNumRec << 8 | pRecCount[1];
			dwNumRec = dwNumRec << 8 | pRecCount[0];

			/* Compute the record length. */
			dwRecLen = pRecSize[2];
			dwRecLen = dwRecLen << 8 | pRecSize[1];
			dwRecLen = dwRecLen << 8 | pRecSize[0];

			/* Should should provide atleast wRecLen / wNumRec to update in TIM collection */
			if(!dwRecLen && !dwNumRec)
			{
				return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
			}

			/* Buffer the Command information to TMI buffer. */
			PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
				(PH_TMIUTILS_READ_INS | PH_TMIUTILS_ZEROPAD_CMDBUFF), pAppData, wAppDataLen, NULL, 0, PHAL_MFDFEVX_BLOCK_SIZE));
		}
    }

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		bLengthPresent,
		3,
		PH_ON,
		(pRecSize[0] | (pRecSize[1] << 8) | (pRecSize[2] << 8)) + 7,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		wOption,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		ppResponse,
		pRespLen,
		aPiccRetCode,
		&bPiccRetCodeLen);

    /* Evaluate the response. */
	wStatus = phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, aPiccRetCode);

	/* Get the TMI Status. */
	PH_CHECK_SUCCESS_FCT(wStatus1, phTMIUtils_GetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams, PH_TMIUTILS_TMI_STATUS,
		&dwTMIStatus));

	/* Check TMI Collection Status */
	if (dwTMIStatus && ((wStatus == PH_ERR_SUCCESS) || ((wStatus & PH_ERR_MASK) == PH_ERR_SUCCESS_CHAINING)))
	{
		/* Frame the Option. */
		bTMIOption = (uint8_t) ((wStatus == PH_ERR_SUCCESS) ? PH_TMIUTILS_ZEROPAD_DATABUFF : PH_TMIUTILS_NO_PADDING);

		/* Collect the data received. */
		PH_CHECK_SUCCESS_FCT(wStatus1, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
			bTMIOption, NULL, 0, *ppResponse, *pRespLen, PHAL_MFDFEVX_BLOCK_SIZE));

		/* Reset the TMI buffer Offset. */
		if (!dwLength && (wStatus == PH_ERR_SUCCESS))
		{
			/* Reset wOffsetInTMI */
			PH_CHECK_SUCCESS_FCT(wStatus1, phTMIUtils_SetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
				PH_TMIUTILS_TMI_OFFSET_LENGTH, 0));
		}
	}

    return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_WriteRecord(void * pDataParams, uint8_t bOption, uint8_t bIns, uint8_t bFileNo, uint8_t * pOffset, uint8_t * pData, uint8_t * pDataLen)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
	uint16_t	PH_MEMLOC_REM wBufferOption = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
	uint8_t		PH_MEMLOC_REM bLenPresent = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint16_t    PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataOffset = 0;
    uint8_t     PH_MEMLOC_REM aPiccRetCode[2];
	uint8_t		PH_MEMLOC_REM bPiccRetCodeLen = 0;
	uint8_t		PH_MEMLOC_REM bIsFirstFrame = PH_ON;
	uint8_t		PH_MEMLOC_REM bDataLen = 0;
	uint8_t		PH_MEMLOC_REM bOffset = 0;
	uint32_t	PH_MEMLOC_REM dwTotLen = 0;
	uint32_t	PH_MEMLOC_REM dwRemLen = 0;
	uint8_t		PH_MEMLOC_REM bExchangeComplete = 0;
    uint32_t	PH_MEMLOC_REM dwTMIStatus = 0;
	
	/* Validate the parameters */
	if (((bFileNo & 0x7f) > 0x1f) || (bIns > 0x01))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}
	if ((bOption != PHAL_MFDFEVX_COMMUNICATION_PLAIN) &&
		(bOption != PHAL_MFDFEVX_COMMUNICATION_ENC) &&
		(bOption != PHAL_MFDFEVX_COMMUNICATION_MACD))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Compute the maximum length. */
	dwTotLen = (uint32_t) (pDataLen[0] | (pDataLen[1] << 8) | (pDataLen[2] << 16));

	/* Update Offset information in case FULL Mode. */
	if((bOption == PHAL_MFDFEVX_COMMUNICATION_ENC) &&
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
	{
		pAppData[wAppDataLen++] = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? 12 : 8);
		pAppData[0] = (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode && (bIns && ( dwTotLen > 0xFE))) ? 
			(pAppData[0] + 2) : pAppData[0]);

		/* Set Length Presence flag. */
		bLenPresent = PH_ON;

		/* Set the Application data offset. This should not go for TMI collection. */
		wAppDataOffset = 1;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = (uint8_t) (bIns ? PHAL_MFDFEVX_CMD_WRITE_RECORD_ISO : PHAL_MFDFEVX_CMD_WRITE_RECORD);
	pAppData[wAppDataLen++] = bFileNo;

	memcpy(&pAppData[wAppDataLen], pOffset, 3);
	wAppDataLen += 3;

	memcpy(&pAppData[wAppDataLen], pDataLen, 3);
	wAppDataLen += 3;
	
	/* Get the TMI Status. */
	PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_GetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams, PH_TMIUTILS_TMI_STATUS,
		&dwTMIStatus));

	/* Check TMI Collection Status */
	if (dwTMIStatus)
	{
		/* Buffer the Command and Data information to TMI buffer. */
		PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
			(PH_TMIUTILS_ZEROPAD_CMDBUFF | PH_TMIUTILS_ZEROPAD_DATABUFF), &pAppData[wAppDataOffset], (uint16_t) (wAppDataLen - wAppDataOffset), 
			pData, dwTotLen, PHAL_MFDFEVX_BLOCK_SIZE));
	}
	
	/* Set the buffering flag. */
	wBufferOption = (uint16_t) (PH_EXCHANGE_DEFAULT | PH_EXCHANGE_TXCHAINING);

	/* Set the lengths. */
	dwRemLen = dwTotLen;

	do
	{
		/* Compute the maximum data to be exchanged.  */
		if(bIsFirstFrame)
		{
			bDataLen = (uint8_t) (PHAL_MFDFEVX_MAX_WRITE_LEN - 8) /* The command header information is available. */;
			bDataLen = (uint8_t) ((bOption == PHAL_MFDFEVX_COMMUNICATION_ENC) ? (bDataLen - 4) : bDataLen);

			if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode)
			{
				bDataLen = (uint8_t) ((bOption == PHAL_MFDFEVX_COMMUNICATION_ENC) ? (bDataLen - 16) : (bDataLen - 20));
			}
		}
		else
		{
			if(bIns)
			{
				bDataLen = (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? (PHAL_MFDFEVX_MAX_WRITE_LEN - 5) : PHAL_MFDFEVX_MAX_WRITE_LEN));
			}
			else
			{
				bDataLen = (uint8_t) (PHAL_MFDFEVX_MAX_WRITE_LEN - 1);
				if(bOption == PHAL_MFDFEVX_COMMUNICATION_ENC)
				{
					bDataLen = (uint8_t) (((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEAES) ||
										   (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)) ?
										   (bDataLen - 11) : (bDataLen - 3));
				}

				if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode)
				{
					bDataLen = (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2) ? 16 : 32);
				}
			}
		}

		/* Set the completion flag. */
		if(dwRemLen <= bDataLen)
		{
			bDataLen = (uint8_t) dwRemLen;
			wBufferOption = PH_EXCHANGE_DEFAULT;
			bExchangeComplete = PH_ON;
		}

		/* Copy the data to the buffer. */
		memcpy(&pAppData[wAppDataLen], &pData[bOffset], bDataLen);
		wAppDataLen += bDataLen;

		/* Wrap the command if required. */
		if(bIsFirstFrame || !bIns)
		{
			PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
				pDataParams,
				PH_ON,
				bLenPresent,
				1,
				PH_OFF,
				(dwTotLen + 7),
				pAppData,
				&wAppDataLen));
		}

		/* Frame the Crypto information. */
		bCrypto = (uint8_t) (bOption | ((bIns && ( dwTotLen > PHAL_MFDFEVX_MAX_WRITE_LEN))? PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_ISO_CHAINING : 
			PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_DESFIRE_CHAINING));

		/* Set the Offset information for MAC and FULL mode. */
		if(bOption != PHAL_MFDFEVX_COMMUNICATION_PLAIN)
		{
			bCrypto |= (uint8_t) (bIsFirstFrame ? 8 : bIns ? 0 : 1);
			bCrypto |= (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode) ? (bCrypto + 4) : bCrypto);
			bCrypto = (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode && (bIns && ( dwTotLen > 0xFE))) ? 
				(bCrypto + 2) : bCrypto);

			/* Reset the Crypto to zero . */
			if(bIns && !bIsFirstFrame)
			{
				bCrypto = 0;
			}
		}

		/* Set ExtendedOffset for Full mode and ISO Chaining. */
		if((bOption == PHAL_MFDFEVX_COMMUNICATION_ENC) && bIsFirstFrame &&
			(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
		{
			/* Mask out the previously set offset. */
			bCrypto = (uint8_t) (bCrypto & 0xF0);

			/* Set the Extended Offset bit. */
			bCrypto |= PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_EXTENDED_OFFSET;
		}

		/* Clear the first frame and Length Presence flag. */
		bIsFirstFrame = PH_OFF;
		bLenPresent = PH_OFF;

		/* Enchange the information to SAM. */
		wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
			wBufferOption,
			bCrypto,
			pAppData,
			(uint8_t) wAppDataLen,
			aPiccRetCode,
			&bPiccRetCodeLen);

		/* Evaluate the response. */
		wStatus = phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, aPiccRetCode);

		/* Return the status if not SUCCESS or SUCCESS_CHAINING. */
		if((wStatus != PH_ERR_SUCCESS) && ((wStatus & PH_ERR_MASK) != PH_ERR_SUCCESS_CHAINING))
		{
			return wStatus;
		}

		/* Update length. */
		bOffset += bDataLen;
		dwRemLen = (uint32_t) (dwRemLen - bDataLen);
		
		/* Set the Chaining satus. */
		wAppDataLen = 0;

		if(!bIns)
		{
			pAppData[wAppDataLen++] = PHAL_MFDFEVX_RESP_ADDITIONAL_FRAME;
		}

	}while(!bExchangeComplete);

    return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_UpdateRecord(void * pDataParams, uint8_t bOption, uint8_t bIns, uint8_t bFileNo, uint8_t * pRecNo, uint8_t * pOffset, uint8_t * pData,
	uint8_t * pDataLen)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
	uint16_t	PH_MEMLOC_REM wBufferOption = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
	uint8_t		PH_MEMLOC_REM bLenPresent = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint16_t    PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataOffset = 0;
    uint8_t     PH_MEMLOC_REM aPiccRetCode[2];
	uint8_t		PH_MEMLOC_REM bPiccRetCodeLen = 0;
	uint8_t		PH_MEMLOC_REM bIsFirstFrame = PH_ON;
	uint8_t		PH_MEMLOC_REM bDataLen = 0;
	uint8_t		PH_MEMLOC_REM bOffset = 0;
	uint32_t	PH_MEMLOC_REM dwTotLen = 0;
	uint32_t	PH_MEMLOC_REM dwRemLen = 0;
	uint8_t		PH_MEMLOC_REM bExchangeComplete = 0;
    uint32_t	PH_MEMLOC_REM dwTMIStatus = 0;
	
	/* Validate the parameters */
	if (((bFileNo & 0x7f) > 0x1f) || (bIns > 0x01))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}
	if ((bOption != PHAL_MFDFEVX_COMMUNICATION_PLAIN) &&
		(bOption != PHAL_MFDFEVX_COMMUNICATION_ENC) &&
		(bOption != PHAL_MFDFEVX_COMMUNICATION_MACD))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Compute the maximum length. */
	dwTotLen = (uint32_t) (pDataLen[0] | (pDataLen[1] << 8) | (pDataLen[2] << 16));

	/* Update Offset information in case FULL Mode. */
	if((bOption == PHAL_MFDFEVX_COMMUNICATION_ENC) &&
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
	{
		pAppData[wAppDataLen++] = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? 15 : 11);
		pAppData[0] = (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode && (bIns && ( dwTotLen > 0xFE))) ? 
			(pAppData[0] + 2) : pAppData[0]);

		/* Set Length Presence flag. */
		bLenPresent = PH_ON;

		/* Set the Application data offset. This should not go for TMI collection. */
		wAppDataOffset = 1;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = (uint8_t) (bIns ? PHAL_MFDFEVX_CMD_UPDATE_RECORD_ISO : PHAL_MFDFEVX_CMD_UPDATE_RECORD);
	pAppData[wAppDataLen++] = bFileNo;

	memcpy(&pAppData[wAppDataLen], pRecNo, 3);
	wAppDataLen += 3;

	memcpy(&pAppData[wAppDataLen], pOffset, 3);
	wAppDataLen += 3;

	memcpy(&pAppData[wAppDataLen], pDataLen, 3);
	wAppDataLen += 3;
	
	/* Get the TMI Status. */
	PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_GetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams, PH_TMIUTILS_TMI_STATUS,
		&dwTMIStatus));

	/* Check TMI Collection Status */
	if (dwTMIStatus)
	{
		/* Buffer the Command and Data information to TMI buffer. */
		PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
			(PH_TMIUTILS_ZEROPAD_CMDBUFF | PH_TMIUTILS_ZEROPAD_DATABUFF), &pAppData[wAppDataOffset], (uint16_t) (wAppDataLen - wAppDataOffset), 
			pData, dwTotLen, PHAL_MFDFEVX_BLOCK_SIZE));
	}
	
	/* Set the buffering flag. */
	wBufferOption = (uint16_t) (PH_EXCHANGE_DEFAULT | PH_EXCHANGE_TXCHAINING);

	/* Set the lengths. */
	dwRemLen = dwTotLen;

	do
	{
		/* Compute the maximum data to be exchanged.  */
		if(bIsFirstFrame)
		{
			bDataLen = (uint8_t) (PHAL_MFDFEVX_MAX_WRITE_LEN - 11) /* The command header information is available. */;
			bDataLen = (uint8_t) ((bOption == PHAL_MFDFEVX_COMMUNICATION_ENC) ? (bDataLen - 4) : bDataLen);

			if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode)
			{
				bDataLen = (uint8_t) ((bOption == PHAL_MFDFEVX_COMMUNICATION_ENC) ? (bDataLen - 16) : (bDataLen - 20));
			}
		}
		else
		{
			if(bIns)
			{
				bDataLen = (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? (PHAL_MFDFEVX_MAX_WRITE_LEN - 5) : PHAL_MFDFEVX_MAX_WRITE_LEN));
			}
			else
			{
				bDataLen = (uint8_t) (PHAL_MFDFEVX_MAX_WRITE_LEN - 1);
				if(bOption == PHAL_MFDFEVX_COMMUNICATION_ENC)
				{
					bDataLen = (uint8_t) (((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEAES) ||
										   (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)) ?
										   (bDataLen - 11) : (bDataLen - 3));
				}

				if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode)
				{
					bDataLen = (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2) ? 16 : 32);
				}
			}
		}

		/* Set the completion flag. */
		if(dwRemLen <= bDataLen)
		{
			bDataLen = (uint8_t) dwRemLen;
			wBufferOption = PH_EXCHANGE_DEFAULT;
			bExchangeComplete = PH_ON;
		}

		/* Copy the data to the buffer. */
		memcpy(&pAppData[wAppDataLen], &pData[bOffset], bDataLen);
		wAppDataLen += bDataLen;

		/* Wrap the command if required. */
		if(bIsFirstFrame || !bIns)
		{
			PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
				pDataParams,
				PH_ON,
				bLenPresent,
				1,
				PH_OFF,
				(dwTotLen + 10),
				pAppData,
				&wAppDataLen));
		}

		/* Frame the Crypto information. */
		bCrypto = (uint8_t) (bOption | ((bIns && ( dwTotLen > PHAL_MFDFEVX_MAX_WRITE_LEN))? PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_ISO_CHAINING : 
			PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_DESFIRE_CHAINING));

		/* Set the Offset information for MAC and FULL mode. */
		if(bOption != PHAL_MFDFEVX_COMMUNICATION_PLAIN)
		{
			bCrypto |= (uint8_t) (bIsFirstFrame ? 11 : bIns ? 0 : 1);
			bCrypto |= (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode) ? (bCrypto + 4) : bCrypto);
			bCrypto = (uint8_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode && (bIns && ( dwTotLen > 0xFE))) ? 
				(bCrypto + 2) : bCrypto);

			/* Reset the Crypto to zero . */
			if(bIns && !bIsFirstFrame)
			{
				bCrypto = 0;
			}
		}

		/* Set ExtendedOffset for Full mode and ISO Chaining. */
		if((bOption == PHAL_MFDFEVX_COMMUNICATION_ENC) && bIsFirstFrame &&
			(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
		{
			/* Mask out the previously set offset. */
			bCrypto = (uint8_t) (bCrypto & 0xF0);

			/* Set the Extended Offset bit. */
			bCrypto |= PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_EXTENDED_OFFSET;
		}

		/* Clear the first frame and Length Presence flag. */
		bIsFirstFrame = PH_OFF;
		bLenPresent = PH_OFF;

		/* Enchange the information to SAM. */
		wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
			wBufferOption,
			bCrypto,
			pAppData,
			(uint8_t) wAppDataLen,
			aPiccRetCode,
			&bPiccRetCodeLen);

		/* Evaluate the response. */
		wStatus = phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, aPiccRetCode);

		/* Return the status if not SUCCESS or SUCCESS_CHAINING. */
		if((wStatus != PH_ERR_SUCCESS) && ((wStatus & PH_ERR_MASK) != PH_ERR_SUCCESS_CHAINING))
		{
			return wStatus;
		}

		/* Update length. */
		bOffset += bDataLen;
		dwRemLen = (uint32_t) (dwRemLen - bDataLen);
		
		/* Set the Chaining satus. */
		wAppDataLen = 0;

		if(!bIns)
		{
			pAppData[wAppDataLen++] = PHAL_MFDFEVX_RESP_ADDITIONAL_FRAME;
		}

	}while(!bExchangeComplete);

    return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_ClearRecordFile(void * pDataParams, uint8_t bFileNo)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint16_t    PH_MEMLOC_REM wAppDataSize = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;
    uint8_t     PH_MEMLOC_REM aPiccRetCode[2];
	uint8_t		PH_MEMLOC_REM bPiccRetCodeLen = 0;
	uint32_t	PH_MEMLOC_REM dwTMIStatus = 0;

	/* Validate the parameters. */
	if ((bFileNo & 0x7f) > 0x1f)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_CLEAR_RECORDS_FILE;
	pAppData[wAppDataLen++] = bFileNo;

   /* Get the TMI Status. */
	PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_GetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams, PH_TMIUTILS_TMI_STATUS,
		&dwTMIStatus));

	/* Check TMI Collection Status */
	if (dwTMIStatus)
	{
		/* Buffer the Command and Data information to TMI buffer. */
		PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
			PH_TMIUTILS_ZEROPAD_CMDBUFF, pAppData, 2, NULL, 0, PHAL_MFDFEVX_BLOCK_SIZE));
    }

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		aPiccRetCode,
		&bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}




/* MIFARE DESFire EVx Transaction mamangement commands. -------------------------------------------------------------------------------- */
phStatus_t phalMfdfEVx_Sam_X_CommitTransaction(void * pDataParams, uint8_t bOption, uint8_t * pTMC, uint8_t * pTMV)	
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Validate the parameters. */
	if (bOption > 0x01)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_COMMIT_TXN;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_COMMIT_TXN;

	/* Add Optionif required. */
	if(bOption)
	{
		pAppData[wAppDataLen++] = bOption;
	}

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	/* Copy the data to the parameter */
	if(bOption)
	{
		memcpy(pTMC, &pResponse[0], 4);	/* PRQA S 3200 */
		memcpy(pTMV, &pResponse[4], 8);	/* PRQA S 3200 */
	}

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_AbortTransaction(void * pDataParams)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_MAC;
	}

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_ABORT_TXN;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_ABORT_TXN;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_CommitReaderID(void * pDataParams, uint8_t * pTMRI, uint8_t * pEncTMRI)
{
	phStatus_t	PH_MEMLOC_REM wStatus = 0;
	uint8_t		PH_MEMLOC_REM bISOMode = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
    uint16_t	PH_MEMLOC_REM wAppDataLen = 0;
	uint16_t	PH_MEMLOC_REM wEncTMRILen = 0;
	uint8_t		PH_MEMLOC_REM aPiccErrCode[2];
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;
	uint32_t	PH_MEMLOC_REM dwTMIStatus = 0;

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_COMMIT_READER_ID;

   /* Get the TMI Status. */
	PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_GetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams, PH_TMIUTILS_TMI_STATUS,
		&dwTMIStatus));

	/* Set Native or ISO7816 PICC command format. */
	bISOMode = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode? PHHAL_HW_CMD_SAMAV3_TMRI_ISO_MODE_ISO7816 : 
		PHHAL_HW_CMD_SAMAV3_TMRI_ISO_MODE_NATIVE);

	/* Exchange the details to SAM hardware and get the ENC TMRI. */
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode != PHAL_MFDFEVX_NOT_AUTHENTICATED)
	{
		/* Exchange the command to SamAV3 hardware .*/
		wStatus = phhalHw_SamAV3_Cmd_TMRI_CommitReaderID(
			PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
			bISOMode,
			PHHAL_HW_CMD_SAMAV3_COMMIT_READER_ID_PICC_STATE_DESFIRE,
			0,
			&pResponse,
			&wEncTMRILen,
			aPiccErrCode);

		/* Copy the Response to the parameter. */
		memcpy(pEncTMRI, pResponse, wEncTMRILen);	/* PRQA S 3200 */
		wRespLen = wEncTMRILen;
		
		/* Check TMI Collection Status */
		if (dwTMIStatus && (wStatus == PH_ERR_SUCCESS))
		{
			/* If authenticated, Cmd.CommitReaderID shall update the Transaction MAC Input TMI as follows:
			 * TMI = TMI || Cmd || TMRICur || EncTMRI || ZeroPadding
			 */

			/* Frame the command and send it to card. */
			pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_COMMIT_READER_ID;

			/* Frame the TMRI information. */
			memcpy(&pAppData[wAppDataLen], PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams->bUid, 7 );	/* PRQA S 3200 */
			wAppDataLen += 7;

			pAppData[wAppDataLen] = 0x80;

			PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
				PH_TMIUTILS_ZEROPAD_DATABUFF, pAppData, 17, pEncTMRI, 16, PHAL_MFDFEVX_BLOCK_SIZE));
		}
	}
	else
	{
		/* Frame the command and send it to card. */
		pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_COMMIT_READER_ID;

		/* Add the TMRI to command buffer. */
		memcpy(&pAppData[wAppDataLen], pTMRI, 16 );	/* PRQA S 3200 */
		wAppDataLen += 16;

		/* Check TMI Collection Status */
		if (dwTMIStatus)
		{
			/* If not authenticated, Cmd.CommitReaderID shall update the Transaction MAC Input TMI as follows:
			 * TMI = TMI || Cmd || TMRICur || ZeroPadding
			 */
			PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
				PH_TMIUTILS_ZEROPAD_CMDBUFF, pAppData, wAppDataLen, NULL, 0, PHAL_MFDFEVX_BLOCK_SIZE));
		}

		/* Wrap the command if required. */
		PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
			pDataParams,
			PH_ON,
			PH_OFF,
			0,
			PH_ON,
			(uint16_t) (wAppDataLen - 1),
			pAppData,
			&wAppDataLen));

		/* Exchange the data to SAM. */
		wStatus = phhalHw_SamAV3_Cmd_X_ISO14443_4_Exchange(
			PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
			PH_EXCHANGE_DEFAULT,
			pAppData,
			(uint8_t) wAppDataLen,
			&pResponse,
			&wRespLen);

		/* Set the PICC error code. */
		aPiccErrCode[0] = pResponse[wRespLen];
		aPiccErrCode[1] = pResponse[wRespLen - 1];

		/* Manipulate the status. */
		if((pResponse[wRespLen] != 0x91) && (pResponse[wRespLen - 1] != 0x00))
		{
			wStatus = PH_ADD_COMPCODE(PHHAL_HW_SAMAV3_ERR_MIFARE_GEN, PH_COMP_HAL);
		}

		/* Decrement the RespLen to remove the status. */
		wRespLen -= 2;
	}

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, aPiccErrCode));

	/* Do a Set Config of ADDITIONAL_INFO to set  the length(wLength) of the recieved TMRI */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_SetConfig(pDataParams, PHAL_MFDFEVX_ADDITIONAL_INFO, wRespLen));

	return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}




/* MIFARE DESFire EVx ISO7816-4 commands. ---------------------------------------------------------------------------------------------- */
phStatus_t phalMfdfEVx_Sam_X_IsoSelectFile(void * pDataParams, uint8_t bOption, uint8_t bSelector, uint8_t * pFid, uint8_t * pDFname, uint8_t bDFnameLen, 
	uint8_t	bExtendedLenApdu, uint8_t ** ppFCI, uint16_t * pFCILen)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t	PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;
	uint8_t		PH_MEMLOC_REM aFileId[3] = {'\0'};
	uint16_t    PH_MEMLOC_REM wVal = 0;
	uint8_t		PH_MEMLOC_REM aPiccDfName[7] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00};

	/* Validate the parameters. */
	if( (bDFnameLen > 16) || ((bOption != 0x00) && (bOption != 0x0C)))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	if(bSelector > 0x04)
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_ISO7816_SELECT_FILE;

	/* Frame the command. */
	pAppData[wAppDataLen++] = 0x00;									/* CLA */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_ISO7816_SELECT_FILE; /* INS */
	pAppData[wAppDataLen++] = bSelector;							/* P1 */
	pAppData[wAppDataLen++] = bOption;								/* P2 */

	/* Append LC. */
	if(bExtendedLenApdu)
	{
		pAppData[wAppDataLen++] = 0;
		pAppData[wAppDataLen++] = 0;
	}

	/* Append the payload and LC. */
	if(bSelector == 0x04)
	{
		/* Append LC. */
		pAppData[wAppDataLen++] = bDFnameLen;

		memcpy(&pAppData[wAppDataLen], pDFname, bDFnameLen); /* PRQA S 3200 */
		wAppDataLen += bDFnameLen;
	}
	else
	{
		/* Append LC. */
		pAppData[wAppDataLen++] = 2;

		/* Select MF, DF or EF, by file identifier
		 * Select child DF
		 * Select EF under the current DF, by file identifier
		 * Select parent DF of the current DF 
		 */
		aFileId[1] = pAppData[wAppDataLen++] = pFid[1];
		aFileId[0] = pAppData[wAppDataLen++] = pFid[0];
		aFileId[2] = 0;
	}

	/* Append LE. */
	if(bExtendedLenApdu)
	{
		pAppData[wAppDataLen++] = 0;
	}
	pAppData[wAppDataLen++] = 0;

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_X_ISO14443_4_Exchange(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PH_EXCHANGE_DEFAULT,
		pAppData,
		(uint8_t) wAppDataLen,
		&pResponse,
		&wRespLen);

	/* Convert the PICC status and validate it. */
	wStatus = (phStatus_t) ((pResponse[wRespLen - 2] << 8) | pResponse[wRespLen - 1]);
	wStatus = phalMfdfEVx_Int_ComputeErrorResponse(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams), wStatus);

	if((wStatus & PH_ERR_MASK) == PHAL_MFDFEVX_ERR_DF_7816_GEN_ERROR)
	{
		wVal = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wAdditionalInfo;
	}

	if((wStatus == PH_ERR_SUCCESS) || (wVal == PHAL_MFDFEVX_ISO7816_ERR_LIMITED_FUNCTIONALITY_INS))
	{
		/* Reset Authentication should not be targeted for elementary file selection using file ID */
		if(bSelector !=  0x02)
		{
			/* Reset Authentication Status here */
			phalMfdfEVx_Sam_X_ResetAuthStatus(pDataParams);
		}

		/* ISO wrapped mode is on */
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode = PH_ON;

		/* once the selection Success, update the File Id to master data structure if the selection is done through AID */
		if((bSelector ==  0x00) || (bSelector == 0x01) || (bSelector == 0x02))
		{
			memcpy(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid, aFileId, sizeof(aFileId));	/* PRQA S 3200 */
		}
		else if((bSelector ==  0x04))
		{
			/* Update the file ID to all zeros if DF Name is of PICC. */
			if(memcmp( pDFname, aPiccDfName, 7) == 0)
			{
				aFileId[0] = 0x00;
				aFileId[1] = 0x00;
				aFileId[2] = 0x00;
			}
			else
			{
				aFileId[0] = 0xff;
				aFileId[1] = 0xff;
				aFileId[2] = 0xff;
			}

			memcpy(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pAid, aFileId, sizeof(aFileId));	/* PRQA S 3200 */
		}
		else
		{
			/* Nothing for Secector 0x03. */
		}
	}
	else
	{
		return wStatus;
	}

	/* Copy the response to the buffer */
	*ppFCI = pResponse;
	*pFCILen = wRespLen;

	return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_IsoReadBinary(void * pDataParams, uint16_t wOption, uint8_t bOffset, uint8_t bSfid, uint32_t dwBytesToRead, uint8_t bExtendedLenApdu, 
	uint8_t ** ppResponse, uint16_t * pBytesRead)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;

	/* Validate the parameter. */
	if (wOption == PH_EXCHANGE_DEFAULT)
	{
		if (bSfid & 0x80)
		{
			/* Short file id is supplied */
			if ((bSfid & 0x7FU) > 0x1F)
			{
				/* Error condition */
				return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
			}
		}
	}

	if ((wOption != PH_EXCHANGE_DEFAULT) && (wOption != PH_EXCHANGE_RXCHAINING))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_ISO7816_READ_BINARY;

	/* Frame the command information based on the option. */
    if (wOption == PH_EXCHANGE_DEFAULT)
    {
		pAppData[wAppDataLen++] = 0x00;
        pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_ISO7816_READ_BINARY;
        pAppData[wAppDataLen++] = bSfid;
        pAppData[wAppDataLen++] = bOffset;

		if(bExtendedLenApdu)
		{
			pAppData[wAppDataLen++] = (uint8_t) ((dwBytesToRead & 0x00FF0000) >> 16);
			pAppData[wAppDataLen++] = (uint8_t) ((dwBytesToRead & 0x0000FF00) >> 8);
		}
		pAppData[wAppDataLen++] = (uint8_t) (dwBytesToRead & 0x000000FF);
    }
	else
	{
		pAppData[wAppDataLen++] = PHAL_MFDFEVX_RESP_ADDITIONAL_FRAME;
	}

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_X_ISO14443_4_Exchange(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		wOption,
		pAppData,
		(uint8_t) wAppDataLen,
		ppResponse,
		pBytesRead);

	/* Update the chaining status code with DESFire component. */
	if((wStatus & PH_ERR_MASK) == PH_ERR_SUCCESS_CHAINING)
	{
		return PH_ADD_COMPCODE(PH_ERR_SUCCESS_CHAINING, PH_COMP_AL_MFDFEVX);
	}

	/* Decrement the Lenght if its success. */
	if(wStatus == PH_ERR_SUCCESS)
		*pBytesRead -= 2;

    return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_IsoUpdateBinary(void * pDataParams, uint8_t bOffset, uint8_t bSfid, uint8_t bExtendedLenApdu, uint8_t * pData, uint32_t dwDataLen)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint16_t	PH_MEMLOC_REM wPiccErrCode = 0;
	
	/* Validate the parameters */
	if (bSfid & 0x80)
    {
        /* Short file id is supplied */
        if ((bSfid & 0x7FU) > 0x1F)
        {
            /* Error condition */
            return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
        }
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_ISO7816_UPDATE_BINARY;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = 0x00;
    pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_ISO7816_UPDATE_BINARY;
    pAppData[wAppDataLen++] = bSfid;
    pAppData[wAppDataLen++] = bOffset;
	
	if(bExtendedLenApdu)
	{
		pAppData[wAppDataLen++] = (uint8_t) ((dwDataLen & 0x00FF0000) >> 16);
		pAppData[wAppDataLen++] = (uint8_t) ((dwDataLen & 0x0000FF00) >> 8);
	}
	pAppData[wAppDataLen++] = (uint8_t) (dwDataLen & 0x000000FF);

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;

	/* Exchange the information to Sam. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_BUFFER_FIRST,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		NULL,
		NULL));
	
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_BUFFER_LAST,
		bCrypto,
		pData,
		(uint8_t) dwDataLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Convert the PICC status and validate it. */
	if((wStatus & PH_ERR_MASK) == PHHAL_HW_SAMAV3_ERR_DESFIRE_GEN)
	{
		wPiccErrCode = (phStatus_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode[0] << 8) | 
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode[1]);

		PH_CHECK_SUCCESS_FCT( wStatus, phalMfdfEVx_Int_ComputeErrorResponse(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams), wPiccErrCode));
	}

    return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_IsoReadRecords(void * pDataParams, uint16_t wOption, uint8_t bRecNo, uint8_t bReadAllFromP1, uint8_t bSfid, uint32_t dwBytesToRead,
	uint8_t bExtendedLenApdu, uint8_t ** ppResponse, uint16_t * pBytesRead)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;

	/* Validate the parameter. */
	if (wOption == PH_EXCHANGE_DEFAULT)
	{
		if (bSfid > 0x1F)
		{
			/* Error condition */
			return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
		}
	}

	if ((wOption != PH_EXCHANGE_DEFAULT) && (wOption != PH_EXCHANGE_RXCHAINING))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_ISO7816_READ_RECORDS;

	/* Frame the command information based on the option. */
    if (wOption == PH_EXCHANGE_DEFAULT)
    {
		pAppData[wAppDataLen++] = 0x00;
        pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_ISO7816_READ_RECORDS;
        pAppData[wAppDataLen++] = bRecNo;
        pAppData[wAppDataLen++] = (uint8_t) ((bSfid <<= 3) | (bReadAllFromP1 ? 0x05 : 0x04));

		if(bExtendedLenApdu)
		{
			pAppData[wAppDataLen++] = (uint8_t) ((dwBytesToRead & 0x00FF0000) >> 16);
			pAppData[wAppDataLen++] = (uint8_t) ((dwBytesToRead & 0x0000FF00) >> 8);
		}
		pAppData[wAppDataLen++] = (uint8_t) (dwBytesToRead & 0x000000FF);
    }
	else
	{
		pAppData[wAppDataLen++] = PHAL_MFDFEVX_RESP_ADDITIONAL_FRAME;
	}

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_X_ISO14443_4_Exchange(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		wOption,
		pAppData,
		(uint8_t) wAppDataLen,
		ppResponse,
		pBytesRead);

	/* Update the chaining status code with DESFire component. */
	if((wStatus & PH_ERR_MASK) == PH_ERR_SUCCESS_CHAINING)
	{
		return PH_ADD_COMPCODE(PH_ERR_SUCCESS_CHAINING, PH_COMP_AL_MFDFEVX);
	}

	/* Decrement the Lenght if its success. */
	if(wStatus == PH_ERR_SUCCESS)
		*pBytesRead -= 2;

    return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_IsoAppendRecord(void * pDataParams, uint8_t bSfid, uint8_t bExtendedLenApdu, uint8_t * pData, uint32_t dwDataLen)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint16_t	PH_MEMLOC_REM wPiccErrCode = 0;
	
	/* Short file id is supplied */
    if ((bSfid & 0x7FU) > 0x1F)
    {
        /* Error condition */
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_ISO7816_APPEND_RECORD;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = 0x00;
    pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_ISO7816_APPEND_RECORD;
    pAppData[wAppDataLen++] = 0x00;
    pAppData[wAppDataLen++] = (uint8_t) (bSfid << 3);
	
	if(bExtendedLenApdu)
	{
		pAppData[wAppDataLen++] = (uint8_t) ((dwDataLen & 0x00FF0000) >> 16);
		pAppData[wAppDataLen++] = (uint8_t) ((dwDataLen & 0x0000FF00) >> 8);
	}
	pAppData[wAppDataLen++] = (uint8_t) (dwDataLen & 0x000000FF);

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;

	/* Exchange the information to Sam. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_BUFFER_FIRST,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		NULL,
		NULL));
	
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_BUFFER_LAST,
		bCrypto,
		pData,
		(uint8_t) dwDataLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Convert the PICC status and validate it. */
	if((wStatus & PH_ERR_MASK) == PHHAL_HW_SAMAV3_ERR_DESFIRE_GEN)
	{
		wPiccErrCode = (phStatus_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode[0] << 8) | 
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode[1]);

		PH_CHECK_SUCCESS_FCT( wStatus, phalMfdfEVx_Int_ComputeErrorResponse(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams), wPiccErrCode));
	}

    return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_IsoGetChallenge(void * pDataParams, uint16_t wKeyNo, uint16_t wKeyVer, uint32_t dwLe, uint8_t * pRPICC1)
{
    pRPICC1 = NULL;
    PHAL_MFDFEVX_UNUSED_VARIABLE(pDataParams);
    PHAL_MFDFEVX_UNUSED_VARIABLE(wKeyNo);
    PHAL_MFDFEVX_UNUSED_VARIABLE(wKeyVer);
    PHAL_MFDFEVX_UNUSED_VARIABLE(dwLe);
    PHAL_MFDFEVX_UNUSED_VARIABLE(pRPICC1);

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_NOT_AUTHENTICATED;

    return PH_ADD_COMPCODE(PH_ERR_UNSUPPORTED_COMMAND, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_IsoExternalAuthenticate(void * pDataParams, uint8_t * pDataIn, uint8_t bInputLen, uint8_t * pDataOut, uint8_t * pOutLen)
{
    PHAL_MFDFEVX_UNUSED_VARIABLE(pDataParams);
    PHAL_MFDFEVX_UNUSED_VARIABLE(pDataIn);
    PHAL_MFDFEVX_UNUSED_VARIABLE(bInputLen);
    PHAL_MFDFEVX_UNUSED_VARIABLE(pDataOut);
    PHAL_MFDFEVX_UNUSED_VARIABLE(pOutLen);

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_NOT_AUTHENTICATED;

    return PH_ADD_COMPCODE(PH_ERR_UNSUPPORTED_COMMAND, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_IsoInternalAuthenticate(void * pDataParams, uint8_t * pDataIn, uint8_t bInputLen, uint8_t * pDataOut, uint8_t * pOutLen)
{
    PHAL_MFDFEVX_UNUSED_VARIABLE(pDataParams);
    PHAL_MFDFEVX_UNUSED_VARIABLE(pDataIn);
    PHAL_MFDFEVX_UNUSED_VARIABLE(bInputLen);
    PHAL_MFDFEVX_UNUSED_VARIABLE(pDataOut);
    PHAL_MFDFEVX_UNUSED_VARIABLE(pOutLen);

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_NOT_AUTHENTICATED;

	/* This command is available only in AV1 Mode */
    return PH_ADD_COMPCODE(PH_ERR_UNSUPPORTED_COMMAND, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_IsoAuthenticate(void * pDataParams, uint16_t wKeyNo, uint16_t wKeyVer, uint8_t bKeyNoCard, uint8_t bIsPICCkey)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
	uint8_t		PH_MEMLOC_REM bOption = 0;
	uint16_t	PH_MEMLOC_REM wPiccErrCode = 0;

    /* Check for valid card key number. */
    if (bKeyNoCard > 0x0d)
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    /* Check for valid SAM keystore number and version. */
    if ((wKeyNo > 0x7f) || (wKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_AUTHENTICATE_ISO;

    /* Unset the current authentication status. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode = PHAL_MFDFEVX_NOT_AUTHENTICATED;
    PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bKeyNo = 0xFF;

	/* Frame the Option parameter. */
	bOption = (uint8_t) (bIsPICCkey ? PHHAL_HW_CMD_SAMAV3_KEY_SELECTION_DESFIRE_KEY_NUMBER : 
		PHHAL_HW_CMD_SAMAV3_KEY_SELECTION_KEY_ENTRY_NUMBER);

	/* Exchange the information to SAM. */
    wStatus = phhalHw_SamAV3_Cmd_DESFire_AuthenticatePICC(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
        bOption,
        PHHAL_HW_CMD_SAMAV3_ISO_MODE_ISO_AUTHENTICATION,
        bKeyNoCard,
        (uint8_t) wKeyNo,
        (uint8_t) wKeyVer,
		0,
		NULL,
        NULL,
        0,
		NULL,
		NULL,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode);

	/* Convert the PICC status and validate it. */
	if((wStatus & PH_ERR_MASK) == PHHAL_HW_SAMAV3_ERR_DESFIRE_GEN)
	{
		wPiccErrCode = (uint16_t) ((PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode[0] << 8) | 
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode[1]);

		PH_CHECK_SUCCESS_FCT( wStatus, phalMfdfEVx_Int_ComputeErrorResponse(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams), wPiccErrCode));
	}

    PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode = PHAL_MFDFEVX_AUTHENTICATEISO;
    PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bKeyNo = bKeyNoCard;
    PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode = PH_ON;

    return wStatus;
}




/* MIFARE DESFire EVx Originality Check functions. ------------------------------------------------------------------------------------- */
phStatus_t phalMfdfEVx_Sam_X_ReadSign(void * pDataParams, uint8_t bAddr, uint8_t ** pSignature)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
	uint8_t     PH_MEMLOC_REM bLengthPresent = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Frame the Crypto information. */
	bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_FULL;
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_NOT_AUTHENTICATED)
	{
		bCrypto = PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_PLAIN;
	}

	/* Add Length information is Communication mode is FULL. */
	if(bCrypto == PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_COMM_MODE_FULL)
	{
		pAppData[wAppDataLen++] = 56;
		pAppData[wAppDataLen++] = 0;
		pAppData[wAppDataLen++] = 0;

		/* Set presence of Length information. */
		bLengthPresent = PH_ON;
	}

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_READ_SIG;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_READ_SIG;
	pAppData[wAppDataLen++] = bAddr;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		bLengthPresent,
		3,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_ReadX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		pSignature,
		&wRespLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}




/* MIFARE DESFire EVx MIFARE Classic functions. ---------------------------------------------------------------------------------------- */
phStatus_t phalMfdfEVx_Sam_X_CreateMFCMapping(void * pDataParams, uint8_t bComOption, uint8_t bFileNo, uint8_t bFileOption, 
	uint8_t * pMFCBlockList, uint8_t bMFCBlocksLen, uint8_t bRestoreSource, uint8_t * pMFCLicense, uint8_t bMFCLicenseLen,
	uint8_t * pMFCLicenseMAC)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
	uint8_t     PH_MEMLOC_REM bOffset = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t		PH_MEMLOC_REM bLenPresent = 0;

	/* Validate the parameters. */
	if((bComOption != PHAL_MFDFEVX_COMMUNICATION_PLAIN) &&
	   (bComOption != PHAL_MFDFEVX_COMMUNICATION_ENC))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	if((bComOption == PHAL_MFDFEVX_COMMUNICATION_ENC) &&
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode != PHAL_MFDFEVX_AUTHENTICATEEV2))
		return PH_ADD_COMPCODE(PH_ERR_AUTH_NOT_SUPPORTED, PH_COMP_AL_MFDFEVX);

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */
		
	/* Frame the Crypto information. */
	bCrypto = bComOption;
	bCrypto |= PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_ISO_CHAINING;
	
	/* Set the Command Offset. */
	if((bComOption == PHAL_MFDFEVX_COMMUNICATION_ENC) &&
		(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode == PHAL_MFDFEVX_AUTHENTICATEEV2))
	{
		/* Start of data. */
		pAppData[wAppDataLen++] = 0;

		/* Set Extended Offset in Crypto mode. */
		bCrypto |= PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_EXTENDED_OFFSET;

		/* Set Length Presence flag. */
		bLenPresent = PH_ON;
	}

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_CREATE_MFC_MAPPING;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_CREATE_MFC_MAPPING;
	pAppData[wAppDataLen++] = bFileNo;
	pAppData[wAppDataLen++] = bFileOption;
    pAppData[wAppDataLen++] = bMFCBlocksLen;

	/* Copy the MFCBlockList to command buffer. */
	memcpy(&pAppData[wAppDataLen], pMFCBlockList, bMFCBlocksLen); /* PRQA S 3200 */
	wAppDataLen += bMFCBlocksLen;

	/* Copy RestoreSource to command buffer. */
	if(bFileOption & 0x04)
	{
		pAppData[wAppDataLen++] = bRestoreSource;
	}

	/* Copy the MFCLicense to command buffer. */
	memcpy(&pAppData[wAppDataLen], pMFCLicense, bMFCLicenseLen); /* PRQA S 3200 */
	wAppDataLen += bMFCLicenseLen;

	/* Compute the Offset. */
	bOffset = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? (wAppDataLen + 4) : wAppDataLen);
	bOffset = (uint8_t) (bOffset - 1);

	/* Reset the Command Offset. */
	if(bComOption == PHAL_MFDFEVX_COMMUNICATION_ENC) 
		pAppData[0] = bOffset;

	/* Copy the MFCLicenseMac to command buffer. */
	memcpy(&pAppData[wAppDataLen], pMFCLicenseMAC, 8); /* PRQA S 3200 */
	wAppDataLen += 8;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		bLenPresent,
		1,
		PH_OFF,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCrypto,
		pAppData,
		(uint8_t) wAppDataLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_RestoreTransfer(void * pDataParams, uint8_t bCommOption, uint8_t bTargetFileNo, uint8_t bSourceFileNo)
{
	phStatus_t	PH_MEMLOC_REM wStatus = 0;
	uint8_t *	PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t	PH_MEMLOC_REM wAppDataLen = 0;
	uint32_t	PH_MEMLOC_REM dwTMIStatus = 0;

	/* Validate the parameters. */
	if ((bCommOption != PHAL_MFDFEVX_COMMUNICATION_PLAIN) &&
		(bCommOption != PHAL_MFDFEVX_COMMUNICATION_PLAIN_1) &&
		(bCommOption != PHAL_MFDFEVX_COMMUNICATION_MACD))
	{
		return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
	}

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_RESTORE_TRANSFER;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_RESTORE_TRANSFER;
	pAppData[wAppDataLen++] = bTargetFileNo;
	pAppData[wAppDataLen++] = bSourceFileNo;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		PH_OFF,
		0,
		PH_ON,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		bCommOption,
		pAppData,
		(uint8_t) wAppDataLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

	/* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

	/* Get the status of the TMI */
	PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_GetConfig(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
		PH_TMIUTILS_TMI_STATUS, &dwTMIStatus));

	/* Check TMI Collection Status */
	if (dwTMIStatus == PH_ON)
	{
		PH_CHECK_SUCCESS_FCT(wStatus, phTMIUtils_CollectTMI(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTMIDataParams,
			PH_TMIUTILS_ZEROPAD_CMDBUFF, pAppData, 3, NULL, 0, PHAL_MFDFEVX_BLOCK_SIZE));
	}

	return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_RestrictMFCUpdate(void * pDataParams, uint8_t bOption, uint8_t * pMFCConfig, uint8_t bMFCConfigLen,
	uint8_t * pMFCLicense, uint8_t bMFCLicenseLen, uint8_t * pMFCLicenseMAC)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;
    uint8_t     PH_MEMLOC_REM bCrypto = 0;
	uint8_t     PH_MEMLOC_REM bOffset = 0;
    uint8_t *   PH_MEMLOC_REM pAppData = NULL;
	uint16_t	PH_MEMLOC_REM wAppDataSize = 0;
	uint16_t    PH_MEMLOC_REM wAppDataLen = 0;
	uint8_t		PH_MEMLOC_REM bLenPresent = 0;

	/* Validate Authentication. */
	if(PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode != PHAL_MFDFEVX_AUTHENTICATEEV2)
		return PH_ADD_COMPCODE(PH_ERR_AUTH_NOT_SUPPORTED, PH_COMP_AL_MFDFEVX);

	/* Get the Global parameters. */
	pAppData = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	wAppDataSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the AppData buffer and length. */
	wAppDataLen = 0;
	memset(pAppData, 0x00, wAppDataSize * sizeof(uint8_t));	/* PRQA S 3200 */
		
	/* Frame the Crypto information. */
	bCrypto = PHAL_MFDFEVX_COMMUNICATION_ENC;
	bCrypto |= PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_ISO_CHAINING;
	bCrypto |= PHHAL_HW_CMD_SAMAV3_CRYPTO_CONFIG_EXTENDED_OFFSET;

	/* Set Length Presence flag. */
	bLenPresent = PH_ON;

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_RESTRICT_MFC_UPDATE;
	
	/* Start of data. */
	pAppData[wAppDataLen++] = 0;

	/* Frame the command information. */
	pAppData[wAppDataLen++] = PHAL_MFDFEVX_CMD_RESTRICT_MFC_UPDATE;
	pAppData[wAppDataLen++] = bOption;

	/* Copy the MFCConfig to command buffer. */
	memcpy(&pAppData[wAppDataLen], pMFCConfig, bMFCConfigLen); /* PRQA S 3200 */
	wAppDataLen += bMFCConfigLen;

	/* Copy the MFCLicense to command buffer. */
	memcpy(&pAppData[wAppDataLen], pMFCLicense, bMFCLicenseLen); /* PRQA S 3200 */
	wAppDataLen += bMFCLicenseLen;

	/* Compute the Offset. */
	bOffset = (uint8_t) (PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode ? (wAppDataLen + 4) : wAppDataLen);
	bOffset = (uint8_t) (bOffset - 1);

	/* Reset the Command Offset. */
	pAppData[0] = bOffset;

	/* Copy the MFCLicenseMac to command buffer. */
	memcpy(&pAppData[wAppDataLen], pMFCLicenseMAC, 8); /* PRQA S 3200 */
	wAppDataLen += 8;

	/* Wrap the command if required. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_Iso7816Wrap(
		pDataParams,
		PH_ON,
		bLenPresent,
		1,
		PH_OFF,
		0,
		pAppData,
		&wAppDataLen));

	/* Exchange the information to Sam. */
	wStatus = phhalHw_SamAV3_Cmd_DESFire_WriteX(
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pHalSamDataParams,
		PH_EXCHANGE_DEFAULT,
		PHAL_MFDFEVX_COMMUNICATION_ENC,
		pAppData,
		(uint8_t) wAppDataLen,
		PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode,
		&PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bPiccRetCodeLen);

    /* Evaluate the response. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->aPiccRetCode));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}



/* MIFARE DESFire EVx POST Delivery Configuration function. ---------------------------------------------------------------------------- */
phStatus_t phalMfdfEVx_Sam_X_AuthenticatePDC(void * pDataParams, uint8_t bRfu, uint8_t bKeyNoCard, uint16_t wKeyNum, uint16_t wKeyVer, uint8_t bUpgradeInfo)
{
	phStatus_t	PH_MEMLOC_REM wStatus = 0;
	uint8_t		PH_MEMLOC_REM bPiccErrCode = 0;

	PH_UNUSED_VARIABLE(bRfu);

	/* Set the dataparams with command code. */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bCmdCode = PHAL_MFDFEVX_CMD_AUTH_PDC;

	wStatus = phhalHw_SamAV3_Cmd_PDC_Authenticate(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PHHAL_HW_SAMAV3_PDC_AUTH_DERIVE_UPGRADE_KEY,
		(uint8_t) wKeyNum, 
		(uint8_t) wKeyVer,
		bKeyNoCard,
		&bUpgradeInfo,
		1,
		NULL,
		0,		
		&bPiccErrCode);
		
	/* Return the error code. */
	if ((wStatus & PH_ERR_MASK) == PHHAL_HW_SAMAV3_ERR_MIFARE_GEN)
	{
		/* Compute the response code. */
		PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ValidateResponse(pDataParams, wStatus, &bPiccErrCode));
	}
	else
	{
		return wStatus;
	}

	return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFPEVX);
}




/* MIFARE DESFire EVx Miscellaneous functions. ----------------------------------------------------------------------------------------- */
phStatus_t phalMfdfEVx_Sam_X_GetConfig(void * pDataParams, uint16_t wConfig, uint16_t * pValue)
{
    switch (wConfig)
    {
		case PHAL_MFDFEVX_ADDITIONAL_INFO:
			*pValue = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wAdditionalInfo;
			break;

		case PHAL_MFDFEVX_WRAPPED_MODE:
			*pValue = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode;
			break;

		default:
			return PH_ADD_COMPCODE(PH_ERR_UNSUPPORTED_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_SetConfig(void * pDataParams, uint16_t wConfig, uint16_t wValue)
{
    switch (wConfig)
    {
		case PHAL_MFDFEVX_ADDITIONAL_INFO:
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wAdditionalInfo = wValue;
			break;

		case PHAL_MFDFEVX_WRAPPED_MODE:
			PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bWrappedMode = (uint8_t) wValue;
			break;

		default:
			return PH_ADD_COMPCODE(PH_ERR_UNSUPPORTED_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);    
}

phStatus_t phalMfdfEVx_Sam_X_ResetAuthStatus(void * pDataParams)
{
	phStatus_t  PH_MEMLOC_REM wStatus = 0;

    /* Reset the Authmode and Key number */
	PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bAuthMode = 0xFF;
    PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->bKeyNo = 0XFF;

	/* Kill the PICC Authentication. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_KillAuthentication(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PHHAL_HW_SAMAV3_CMD_SAM_KILL_AUTHENTICATION_PARTIAL));

    return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);    
}

phStatus_t phalMfdfEVx_Sam_X_GenerateDAMEncKey(void * pDataParams, uint16_t wKeyNoDAMEnc, uint16_t wKeyVerDAMEnc, uint16_t wKeyNoAppDAMDefault,
	uint16_t wKeyVerAppDAMDefault, uint8_t bAppDAMDefaultKeyVer, uint8_t * pDAMEncKey)
{	
	phStatus_t	PH_MEMLOC_REM wStatus = 0;
	uint8_t		PH_MEMLOC_REM bKeyLen = 0;
	uint8_t	*	PH_MEMLOC_REM pInputBuff = NULL;
	uint8_t		PH_MEMLOC_REM bInputBuffLen = 0;
	uint16_t	PH_MEMLOC_REM bInputBuffSize = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;
	uint16_t	PH_MEMLOC_REM wSET = 0;
	uint16_t	PH_MEMLOC_REM wExtSET = 0;
	uint16_t	PH_MEMLOC_REM wKeyType = 0;

	/* Validate the key information. */
	if (((wKeyNoDAMEnc > 0x7F) || (wKeyVerDAMEnc > 0xFF)) || 
		(wKeyNoAppDAMDefault > 0x7F) || ((wKeyVerAppDAMDefault > 0x7F) || (bAppDAMDefaultKeyVer > 0xFF)))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }
	
	/* Get the KeyInformation. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_GetKeyInfo(
		pDataParams,
		(uint8_t) wKeyNoAppDAMDefault,
		&wKeyType,
		&wSET,
		&wExtSET));

	/* Validate the KeyType. */
	if((wKeyType != 0x0030) && (wKeyType != 0x0020) &&
		(wKeyType != 0x0018) && (wKeyType != 0x0000))
	{
		return PH_ADD_COMPCODE(PH_ERR_KEY, PH_COMP_AL_MFDFEVX);
	}

	/* Check if DumpSecretKey is enabled. */
	if(!(wExtSET & 0x0008))
	{
		return PH_ADD_COMPCODE(PH_ERR_PROTOCOL_ERROR, PH_COMP_AL_MFDFEVX);
	}
	
	/* Get the KeyInformation. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_GetKeyInfo(
		pDataParams,
		(uint8_t) wKeyNoDAMEnc,
		&wKeyType,
		&wSET,
		&wExtSET));

	/* Validate the KeyType. */
	if((wKeyType != 0x0030) && (wKeyType != 0x0020) &&
		(wKeyType != 0x0018) && (wKeyType != 0x0000))
	{
		return PH_ADD_COMPCODE(PH_ERR_KEY, PH_COMP_AL_MFDFEVX);
	}

	/* Get the Global parameters. */
	pInputBuff = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	bInputBuffSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the command buffer and length. */
	bInputBuffLen = 0;
	memset(pInputBuff, 0x00, bInputBuffSize * sizeof(uint8_t));	/* PRQA S 3200 */
	
	/* Add the Random number. */
	bInputBuffLen = 7;
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_GetRandom(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		bInputBuffLen,
		pInputBuff));

	/* Append the Key. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_DumpSecretKey(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PHHAL_HW_SAMAV3_CMD_SAM_DUMP_MODE_PLAIN,
		(uint8_t) wKeyNoAppDAMDefault,
		(uint8_t) wKeyVerAppDAMDefault,
		NULL,
		0,
		&pInputBuff[bInputBuffLen],
		&bKeyLen));
	bInputBuffLen += bKeyLen;

	/* Append the key version. */
	pInputBuff[bInputBuffLen] = bAppDAMDefaultKeyVer;

	/* Set the Input length to 32 bytes default. */
	bInputBuffLen = 32;

	/* Validate the KeyType. */
	if((wKeyType != 0x0030) && (wKeyType != 0x0020) &&
		(wKeyType != 0x0018) && (wKeyType != 0x0000))
	{
		return PH_ADD_COMPCODE(PH_ERR_KEY, PH_COMP_AL_MFDFEVX);
	}

	/* Perform Offline activation. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_ActivateOfflineKey(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PHHAL_HW_SAMAV3_CMD_SAM_AO_LRP_UPDATE_KEY_RFU,
		(uint8_t) wKeyNoDAMEnc,
		(uint8_t) wKeyVerDAMEnc,
		NULL,
		0));

	/* Encrypt the Plaindata. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_EncipherOfflineData(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PH_EXCHANGE_DEFAULT,
		pInputBuff,
		bInputBuffLen,
		&pResponse,
		&wRespLen));

	/* Copy the response to the parameter. */
	memcpy(pDAMEncKey, pResponse, wRespLen); /* PRQA S 3200 */

	return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_GenerateDAMMAC(void * pDataParams, uint8_t bOption, uint16_t wKeyNoDAMMAC, uint16_t wKeyVerDAMMAC, uint8_t * pAid,
	uint8_t * pDamParams, uint8_t bKeySettings1, uint8_t bKeySettings2, uint8_t bKeySettings3, uint8_t * pKeySetValues, uint8_t * pISOFileId,
	uint8_t * pISODFName, uint8_t bISODFNameLen, uint8_t * pEncK, uint8_t * pDAMMAC)
{
	phStatus_t	PH_MEMLOC_REM wStatus = 0;
	uint8_t	*	PH_MEMLOC_REM pInputBuff = NULL;
	uint8_t		PH_MEMLOC_REM bInputBuffLen = 0;
	uint16_t	PH_MEMLOC_REM bInputBuffSize = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;
	uint16_t	PH_MEMLOC_REM wSET = 0;
	uint16_t	PH_MEMLOC_REM wExtSET = 0;
	uint16_t	PH_MEMLOC_REM wKeyType = 0;

	/* Validate the key information. */
	if ((wKeyNoDAMMAC > 0x7F) || (wKeyVerDAMMAC > 0xFF))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }
	
	/* Get the KeyInformation. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_GetKeyInfo(
		pDataParams,
		(uint8_t) wKeyNoDAMMAC,
		&wKeyType,
		&wSET,
		&wExtSET));

	/* Validate the KeyType. */
	if((wKeyType != 0x0030) && (wKeyType != 0x0020) &&
		(wKeyType != 0x0018) && (wKeyType != 0x0000))
	{
		return PH_ADD_COMPCODE(PH_ERR_KEY, PH_COMP_AL_MFDFEVX);
	}

	/* Get the Global parameters. */
	pInputBuff = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->pTmpBuffer;
	bInputBuffSize = PHAL_MFDFEVX_RESOLVE_DATAPARAMS(pDataParams)->wTmpBufSize;

	/* Clear the command buffer and length. */
	bInputBuffLen = 0;
	memset(pInputBuff, 0x00, bInputBuffSize * sizeof(uint8_t));	/* PRQA S 3200 */

	/* Frame the Input */
	pInputBuff[bInputBuffLen++] = PHAL_MFDFEVX_CMD_CREATE_DELEGATED_APPLN;
	
	if((bOption & PHAL_MFDFEVX_GENERATE_DAMMAC_DELETE_APPLICATION) == PHAL_MFDFEVX_GENERATE_DAMMAC_DELETE_APPLICATION)
		pInputBuff[0] = PHAL_MFDFEVX_CMD_DELETE_APPLN;

	/* Append Application Identifier */
	memcpy(&pInputBuff[bInputBuffLen], pAid, 3);	/* PRQA S 3200 */
	bInputBuffLen += 3;

	if(!(bOption & PHAL_MFDFEVX_GENERATE_DAMMAC_DELETE_APPLICATION))
	{
		/* Append DAMParams */
		memcpy(&pInputBuff[bInputBuffLen], pDamParams, 5);	/* PRQA S 3200 */
		bInputBuffLen += 5;

		/* Append KeySetting Information */
		pInputBuff[bInputBuffLen++] = bKeySettings1;
		pInputBuff[bInputBuffLen++] = bKeySettings2;
		if (bKeySettings2 & PHAL_MFDFEVX_KEYSETT3_PRESENT)
		{
			pInputBuff[bInputBuffLen++] = bKeySettings3;
			if (bKeySettings3 & PHAL_MFDFEVX_KEYSETVALUES_PRESENT && pKeySetValues != NULL)
			{
        		memcpy(&pInputBuff[bInputBuffLen], pKeySetValues, 4); /* PRQA S 3200 */
        		bInputBuffLen += 4;
			}
		}

		/* Append FileID Information */
		if (bOption & PHAL_MFDFEVX_ISO_FILE_ID_AVAILABLE)
		{
			memcpy(&pInputBuff[bInputBuffLen], pISOFileId, 2); /* PRQA S 3200 */
			bInputBuffLen += 2;
		}

		/* Append DFName Information */
		if (bOption & PHAL_MFDFEVX_ISO_DF_NAME_AVAILABLE)
		{
			memcpy(&pInputBuff[bInputBuffLen], pISODFName, bISODFNameLen); /* PRQA S 3200 */
			bInputBuffLen += bISODFNameLen;
		}

		/* Append EncK Information. */
		memcpy(&pInputBuff[bInputBuffLen], pEncK, 32);	/* PRQA S 3200 */
		bInputBuffLen += 32;
	}

	/* Perform Offline activation. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_ActivateOfflineKey(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PHHAL_HW_SAMAV3_CMD_SAM_AO_LRP_UPDATE_KEY_RFU,
		(uint8_t) wKeyNoDAMMAC,
		(uint8_t) wKeyVerDAMMAC,
		NULL,
		0));

	/* Generate the MAC. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_GenerateMAC(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PH_EXCHANGE_DEFAULT,
		PHHAL_HW_SAMAV3_TRUNCATION_MODE_MFP,
		pInputBuff,
		bInputBuffLen,
		&pResponse,
		&wRespLen));

	/* Copy the MAC to parameter. */
	memcpy(pDAMMAC, pResponse, wRespLen);	/* PRQA S 3200 */
	
	return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_CalculateTMV(void * pDataParams, uint16_t wSrcKeyNo, uint16_t wSrcKeyVer, uint16_t wDstKeyNo, 
	uint16_t wDstKeyVer, uint8_t * pTMC, uint8_t * pUid, uint8_t bUidLen, uint8_t * pTMI, uint32_t dwTMILen, uint8_t * pTMV)
{
	phStatus_t	PH_MEMLOC_REM wStatus = 0;
	uint8_t		PH_MEMLOC_REM bFinished = PH_OFF;
	uint8_t *	PH_MEMLOC_REM pMac = NULL;
	uint16_t	PH_MEMLOC_REM wMacLen = 0;

	uint16_t	PH_MEMLOC_REM wBuffOption = PH_EXCHANGE_DEFAULT;
	uint8_t		PH_MEMLOC_REM bExchangeLen = 0;
	uint32_t	PH_MEMLOC_REM dwRemLen = 0;
	uint16_t	PH_MEMLOC_REM wTMIOffset = 0;

	/* Validate the key information. */
	if ((wSrcKeyNo > 0x7f) || (wSrcKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	if (((wDstKeyNo < 0xE0) || (wDstKeyNo > 0xE3)) || (wDstKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Derive Transaction MAC (KSesTMMAC) session key. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ComputeTMACSessionVectors(
		pDataParams,
		PHAL_MFDFEVX_SAM_X_SESSION_TMAC_MAC,
		wSrcKeyNo,
		wSrcKeyVer,
		wDstKeyNo,
		pTMC,
		pUid,
		bUidLen));

	/* Perform Offline activation using Ram Key. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_ActivateOfflineKey(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PHHAL_HW_SAMAV3_CMD_SAM_AO_LRP_UPDATE_KEY_RFU,
		(uint8_t) wDstKeyNo,
		(uint8_t) wDstKeyVer,
		NULL,
		0));

	/* Perform MAC verification. */
	dwRemLen = (uint16_t) dwTMILen;
	wBuffOption = PH_EXCHANGE_TXCHAINING;

	do
	{
		/* Update the finished flag and buffering option. */
		if(dwRemLen <= PHAL_MFDFEVX_SAM_DATA_FRAME_LENGTH)
		{
			bFinished = PH_ON;
			wBuffOption = PH_EXCHANGE_DEFAULT;
			bExchangeLen = (uint8_t) dwRemLen;
		}
		else
		{
			bExchangeLen = PHAL_MFDFEVX_SAM_DATA_FRAME_LENGTH;
			dwRemLen = (uint16_t) (dwRemLen - PHAL_MFDFEVX_SAM_DATA_FRAME_LENGTH);
		}

		/* Exchange the TMI information to SAM. */
		wStatus = phhalHw_SamAV3_Cmd_SAM_GenerateMAC(
			PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
			wBuffOption,
			PHHAL_HW_SAMAV3_TRUNCATION_MODE_MFP,
			&pTMI[wTMIOffset],
			bExchangeLen,
			&pMac,
			&wMacLen);

		/* Validate the response. */
		if(((wStatus & PH_ERR_MASK) != PH_ERR_SUCCESS) && ((wStatus & PH_ERR_MASK) != PH_ERR_SUCCESS_CHAINING))
		{
			bFinished = PH_ON;
		}

		/* Update the TMI offset information. */
		wTMIOffset += PHAL_MFDFEVX_SAM_DATA_FRAME_LENGTH;

	}while(!bFinished);

	/* Copy the Mac to the parameter. */
	memcpy(pTMV, pMac, wMacLen);	/* PRQA S 3200 */

	return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_DecryptReaderID(void * pDataParams, uint16_t wSrcKeyNo, uint16_t wSrcKeyVer, uint16_t wDstKeyNo, 
	uint16_t wDstKeyVer, uint8_t * pTMC, uint8_t * pUid, uint8_t bUidLen, uint8_t * pEncTMRI, uint8_t * pTMRIPrev)
{
	phStatus_t	PH_MEMLOC_REM wStatus = 0;
	uint8_t	*	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Validate the key information. */
	if ((wSrcKeyNo > 0x7f) || (wSrcKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	if (((wDstKeyNo < 0xE0) || (wDstKeyNo > 0xE3)) || (wDstKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Derive Transaction MAC (KSesTMMAC) session key. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ComputeTMACSessionVectors(
		pDataParams,
		PHAL_MFDFEVX_SAM_X_SESSION_TMAC_ENC,
		wSrcKeyNo,
		wSrcKeyVer,
		wDstKeyNo,
		pTMC,
		pUid,
		bUidLen));

	/* Perform Offline activation using Ram Key. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_ActivateOfflineKey(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PHHAL_HW_SAMAV3_CMD_SAM_AO_LRP_UPDATE_KEY_RFU,
		(uint8_t) wDstKeyNo,
		(uint8_t) wDstKeyVer,
		NULL,
		0));
		
	/* Exchange the TMI information to SAM. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_DecipherOfflineData(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PH_EXCHANGE_DEFAULT,
		pEncTMRI,
		16,
		&pResponse,
		&wRespLen));

	/* Copy the decrypted information to the parameter. */
	memcpy(pTMRIPrev, pResponse, wRespLen);	/* PRQA S 3200 */

	return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_ComputeMFCLicenseMAC(void * pDataParams, uint16_t wOption, uint16_t wMFCLicenseMACKeyNo, uint16_t wMFCLicenseMACKeyVer,
	uint8_t * pInput, uint16_t wInputLen, uint8_t * pDivInput, uint8_t bDivInputLen, uint8_t * pMFCLicenseMAC)
{
	phStatus_t	PH_MEMLOC_REM wStatus = 0;
	uint8_t *	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;
	
	uint8_t		PH_MEMLOC_REM bOption = PH_OFF;
	uint8_t		PH_MEMLOC_REM bFinished = PH_OFF;
	uint16_t	PH_MEMLOC_REM wBuffOption = PH_EXCHANGE_DEFAULT;
	uint8_t		PH_MEMLOC_REM bExchangeLen = 0;
	uint16_t	PH_MEMLOC_REM wRemLen = 0;
	uint16_t	PH_MEMLOC_REM wInputOffset = 0;

	/* Validate the key information. */
	if ((wMFCLicenseMACKeyNo > 0x7f) || (wMFCLicenseMACKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Frame the Option parameter. */
	bOption = (uint8_t) ((wOption != PHAL_MFDFEVX_NO_DIVERSIFICATION) ? PHHAL_HW_CMD_SAMAV3_KEY_DIVERSIFICATION_ON : 
		PHHAL_HW_CMD_SAMAV3_KEY_DIVERSIFICATION_OFF);

	/* Perform Offline activation. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_ActivateOfflineKey(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		bOption,
		(uint8_t) wMFCLicenseMACKeyNo,
		(uint8_t) wMFCLicenseMACKeyVer,
		pDivInput,
		bDivInputLen));

	/* Perform MAC generation. */
	wRemLen = wInputLen;
	wBuffOption = PH_EXCHANGE_TXCHAINING;

	do
	{
		/* Update the finished flag and buffering option. */
		if(wRemLen <= PHAL_MFDFEVX_SAM_DATA_FRAME_LENGTH)
		{
			bFinished = PH_ON;
			wBuffOption = PH_EXCHANGE_DEFAULT;
			bExchangeLen = (uint8_t) wRemLen;
		}
		else
		{
			bExchangeLen = PHAL_MFDFEVX_SAM_DATA_FRAME_LENGTH;
			wRemLen = (uint16_t) (wRemLen - PHAL_MFDFEVX_SAM_DATA_FRAME_LENGTH);
		}

		/* Exchange the Input information to SAM. */
		wStatus = phhalHw_SamAV3_Cmd_SAM_GenerateMAC(
			PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
			wBuffOption,
			PHHAL_HW_SAMAV3_TRUNCATION_MODE_MFP,
			&pInput[wInputOffset],
			bExchangeLen,
			&pResponse,
			&wRespLen);

		/* Validate the response. */
		if(((wStatus & PH_ERR_MASK) != PH_ERR_SUCCESS) && ((wStatus & PH_ERR_MASK) != PH_ERR_SUCCESS_CHAINING))
		{
			bFinished = PH_ON;
		}

		/* Update the TMI offset information. */
		wInputOffset += PHAL_MFDFEVX_SAM_DATA_FRAME_LENGTH;

	}while(!bFinished);	

	/* Copy the Mac to the parameter. */
	memcpy(pMFCLicenseMAC, pResponse, wRespLen);	/* PRQA S 3200 */

	return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_CalculateMACSDM(void * pDataParams, uint8_t bSdmOption, uint16_t wSrcKeyNo, uint16_t wSrcKeyVer,
	uint16_t wDstKeyNo, uint16_t wDstKeyVer, uint8_t * pUid, uint8_t bUidLen, uint8_t * pSDMReadCtr, uint8_t * pInData, uint16_t wInDataLen,
	uint8_t * pMac)
{
	phStatus_t	PH_MEMLOC_REM wStatus = 0;
	uint8_t		PH_MEMLOC_REM bFinished = PH_OFF;
	uint8_t *	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	uint16_t	PH_MEMLOC_REM wBuffOption = PH_EXCHANGE_DEFAULT;
	uint8_t		PH_MEMLOC_REM bExchangeLen = 0;
	uint16_t	PH_MEMLOC_REM wRemLen = 0;
	uint16_t	PH_MEMLOC_REM wInputOffset = 0;

	/* Validate the key information. */
	if ((wSrcKeyNo > 0x7f) || (wSrcKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	if (((wDstKeyNo < 0xE0) || (wDstKeyNo > 0xE3)) || (wDstKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Derive SDM MAC (KSesSDMFileReadMAC) session key. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ComputeSDMSessionVectors(
		pDataParams,
		PHAL_MFDFEVX_SAM_X_SESSION_MAC,
		bSdmOption,
		wSrcKeyNo,
		wSrcKeyVer,
		wDstKeyNo,
		pUid,
		bUidLen,
		pSDMReadCtr));

	/* Perform Offline activation using Ram Key. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_ActivateOfflineKey(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PHHAL_HW_SAMAV3_CMD_SAM_AO_LRP_UPDATE_KEY_RFU,
		(uint8_t) wDstKeyNo,
		(uint8_t) wDstKeyVer,
		NULL,
		0));

	/* Perform MAC generation. */
	wRemLen = wInDataLen;
	wBuffOption = PH_EXCHANGE_TXCHAINING;

	do
	{
		/* Update the finished flag and buffering option. */
		if(wRemLen <= PHAL_MFDFEVX_SAM_DATA_FRAME_LENGTH)
		{
			bFinished = PH_ON;
			wBuffOption = PH_EXCHANGE_DEFAULT;
			bExchangeLen = (uint8_t) wRemLen;
		}
		else
		{
			bExchangeLen = PHAL_MFDFEVX_SAM_DATA_FRAME_LENGTH;
			wRemLen = (uint16_t) (wRemLen - PHAL_MFDFEVX_SAM_DATA_FRAME_LENGTH);
		}

		/* Exchange the Input information to SAM. */
		wStatus = phhalHw_SamAV3_Cmd_SAM_GenerateMAC(
			PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
			wBuffOption,
			PHHAL_HW_SAMAV3_TRUNCATION_MODE_MFP,
			&pInData[wInputOffset],
			bExchangeLen,
			&pResponse,
			&wRespLen);

		/* Validate the response. */
		if(((wStatus & PH_ERR_MASK) != PH_ERR_SUCCESS) && ((wStatus & PH_ERR_MASK) != PH_ERR_SUCCESS_CHAINING))
		{
			bFinished = PH_ON;
		}

		/* Update the TMI offset information. */
		wInputOffset += PHAL_MFDFEVX_SAM_DATA_FRAME_LENGTH;

	}while(!bFinished);

	/* Copy the Mac to the parameter. */
	memcpy(pMac, pResponse, wRespLen);	/* PRQA S 3200 */

	return wStatus;
}

phStatus_t phalMfdfEVx_Sam_X_DecryptSDMENCFileData(void * pDataParams, uint8_t bSdmOption, uint16_t wSrcKeyNo, uint16_t wSrcKeyVer, uint16_t wDstKeyNo,
	uint16_t wDstKeyVer, uint8_t * pUid, uint8_t bUidLen, uint8_t * pSDMReadCtr, uint8_t * pEncdata, uint16_t wEncDataLen, uint8_t * pPlainData)
{
	phStatus_t	PH_MEMLOC_REM wStatus = 0;
	uint8_t *	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Validate the key information. */
	if ((wSrcKeyNo > 0x7f) || (wSrcKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	if (((wDstKeyNo < 0xE0) || (wDstKeyNo > 0xE3)) || (wDstKeyVer > 0xff))
    {
        return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_AL_MFDFEVX);
    }

	/* Derive SDM MAC (KSesSDMFileReadMAC) session key. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_ComputeSDMSessionVectors(
		pDataParams,
		PHAL_MFDFEVX_SAM_X_SESSION_ENC,
		bSdmOption,
		wSrcKeyNo,
		wSrcKeyVer,
		wDstKeyNo,
		pUid,
		bUidLen,
		pSDMReadCtr));

	/* Perform Offline activation using Ram Key. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_ActivateOfflineKey(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PHHAL_HW_SAMAV3_CMD_SAM_AO_LRP_UPDATE_KEY_RFU,
		(uint8_t) wDstKeyNo,
		(uint8_t) wDstKeyVer,
		NULL,
		0));

	/* Load the IV. */
	PH_CHECK_SUCCESS_FCT(wStatus, phalMfdfEVx_Sam_X_Int_LoadSDMInitVector(
		pDataParams,
		pSDMReadCtr));

	/* Exchange the Encrypted information to SAM. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_DecipherOfflineData(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PH_EXCHANGE_DEFAULT,
		pEncdata,
		(uint8_t) wEncDataLen,
		&pResponse,
		&wRespLen));

	/* Copy the decrypted information to the parameter. */
	memcpy(pPlainData, pResponse, wRespLen);	/* PRQA S 3200 */

	return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}

phStatus_t phalMfdfEVx_Sam_X_DecryptSDMPICCData(void * pDataParams, uint16_t wKeyNo, uint16_t wKeyVer, uint8_t * pEncdata,
	uint16_t wEncDataLen, uint8_t * pPlainData)
{
	phStatus_t	PH_MEMLOC_REM wStatus = 0;
	uint8_t		PH_MEMLOC_REM bEncDataOffset = 0;
	uint8_t *	PH_MEMLOC_REM pResponse = NULL;
	uint16_t	PH_MEMLOC_REM wRespLen = 0;

	/* Perform Offline activation using Ram Key. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_ActivateOfflineKey(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PHHAL_HW_SAMAV3_CMD_SAM_AO_LRP_UPDATE_KEY_RFU,
		(uint8_t) wKeyNo,
		(uint8_t) wKeyVer,
		NULL,
		0));

	/* Perform DecipherDataOffline. */
	PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SamAV3_Cmd_SAM_DecipherOfflineData(
		PHAL_MFDFEVX_RESOLVE_HAL_DATAPARAMS(pDataParams),
		PH_EXCHANGE_DEFAULT,
		&pEncdata[bEncDataOffset],
		(uint8_t) (wEncDataLen - bEncDataOffset),
		&pResponse,
		&wRespLen));

	/* Copy the decrypted information to the parameter. */
	memcpy(pPlainData, pResponse, wRespLen);	/* PRQA S 3200 */

	return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_AL_MFDFEVX);
}
#endif /* NXPBUILD__PHAL_MFDFEVX_SAM_X */
